#!/usr/bin/env python # coding: utf-8 # # Основы программирования в Python # # *Алла Тамбовцева, НИУ ВШЭ* # # *Данный ноутбук основан на [лекциях](http://math-info.hse.ru/2017-18/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B4%D0%BB%D1%8F_%D0%B4%D0%B0%D1%82%D0%B0-%D0%B6%D1%83%D1%80%D0%BD%D0%B0%D0%BB%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B8) Щурова И.В., курс «Программирование на языке Python для сбора и анализа данных» (НИУ ВШЭ).* # # ## Методы `.split()` и `.join()`, списковые включения # ### Метод `.split()` # Мы уже достаточно хорошо знакомы с вводом какой-то информации с клавиатуры с помощью `input()`. Однако раньше мы всегда вводили с клавиатуры только один объект: одно число или одно слово... А можно ли вводить сразу несколько слов или чисел? Конечно, можно! Посмотрим. # In[1]: heroes = input("Введите имена героев мюзикла Notre Dame de Paris: ") # Выше мы ввели довольно длинную строку: перечислили имена четырех героев через пробел. Посмотрим на нее. # In[2]: heroes # А теперь разобьем эту строку по пробелу, чтобы получить четыре отдельных имени ‒ воспользуемся методом `.split()`. # In[3]: heroes_list = heroes.split() # по умолчанию деление по пробелу heroes_list # Получили самый обычный список. Можем обращаться к его элементам и даже изменять их при желании: # In[4]: heroes_list[1] # Разбивать строку на части можно по любому символу, достаточно указать нужный символ в скобках в `.split()`. # In[5]: fheroes = input("Введите имена любимых героев NDDP через запятую: ") # In[6]: fheroes # In[7]: fheroes.split(",") # Попробуем проделать то же самое, но для чисел. # In[8]: nums = input("Введите два числа: ") nums_list = nums.split() # Список получили, но он пока состоит из строк, не из чисел. # In[9]: nums_list # Поправим: превратим все элементы списка в целые числа с помощью цикла и сохраним их в новый список. # In[10]: final = [] for n in nums_list: final.append(int(n)) final # Чуть позже мы узнаем, как более удобно (и что приятно, более быстро) сделать то же самое, но без цикла. # # А пока узнаем, можно ли разбить строку по пустоте? То есть просто разделить ее на отдельные символы. Попробуем. # In[11]: "1234".split("") # нельзя # Python сообщает нам, что разделитель пустой, и делить строку на части не хочет. # # Раз есть метод для разбиения строки на список строк, должна быть и обратная операция ‒ для склеивания списка строк в одну большую строку. И такой метод действительно есть! # ### Метод `.join()` # Пусть у нас есть список, состоящий из имени и фамилии. # In[12]: l = ['Daniel', 'Lavoie'] # И мы хотим элементы списка склеить в одну строку так, чтобы между именем и фамилией был пробел. # In[13]: " ".join(l) # вуаля # Могли бы вместо пробела в кавычках поставить любой символ, например, нижнее подчеркивание. # In[14]: "_".join(l) # **Важно:** метод `.join()` берет в качестве аргумента именно список, не просто перечисленные элементы через запятую. # In[15]: a = '7' b = '8' " ".join(a,b) # не работает # In[16]: " ".join([a,b]) # работает # Иногда удобно сочетать методы `.split()` и `.join()`. Например, перед нами стоит такая задача. Пользователь вводит дату в формате день-месяц-год через точку, а мы хотим выводить на экран дату в том же формате, но через дефис. Чтобы решить эту задачу, можно взять введенную пользователем строку с датой, разбить ее по точке, а затем склеить части, но уже используя дефис. # In[17]: date = input("Введите дату: ") date # In[18]: parts = date.split(".") result = "-".join(parts) print(result) # ### Метод `.strip()` # При работе со строками можно столкнуться с еще одной сложностью ‒ с пробелами. Если мы попросим пользователя ввести имена героев через запятую, перед запятой он, скорее всего, поставит пробел. # In[19]: # вот так fheroes = input("Введите имена любимых героев NDDP через запятую: ") fheroes # Как быть? Разбить строку по запятой, а потом избавиться от пробела. Избавиться от пробела поможет метод `.strip()`. # In[20]: hero = " Гренгуар" hero.strip() # Метод `.strip()` работает по-умному: он убирает пробелы в начале и в конце строки, пробелы в середине (между словами) никуда не денутся. # In[21]: heroes = " Гренгуар Фролло " heroes.strip() # На самом деле это не случайно. Если посмотреть на все методы для строк, то можно увидеть целых три варианта со`.strip()`: `.lstrip()`, `.rstrip()` и `.strip()`. Метод `.lstrip()` убирает все пробелы в начале строки (слева, *l* ‒ от *left*), метод `.rstrip()` ‒ все пробелы в конце строки (справа, *r* ‒ от *right*), а метод `.strip()`является их объединением, то есть убирает все пробелы в начале и в конце строки. # In[22]: " Гренгуар ".lstrip() # In[23]: " Гренгуар ".rstrip() # In[24]: " Гренгуар ".strip() # ### Списковые включения # Сейчас мы познакомимся со списковыми включениями (*list comprehensions*) ‒ объектами, которые позволяют создавать новые списки на основе старых, без создания пустого списка и заполнения его в цикле. Чтобы понять, что такое списковые включения, лучше сначала посмотреть на пример. Попробуем создать список, состоящий из элементов другого списка, возведенных в квадрат. # In[25]: old = [1, 0, 3, 5] new = [i**2 for i in old] new # Цикл *for* у нас по-прежнему задействован, только немного в ином качестве и в другой последовательности: сначала мы указываем, что нужно делать с элементами, а потом ‒ по каким элементам будем пробегаться. В нашем примере мы говорим, что возводим элементы *i* в квадрат, а потом сообщаем, что эти элементы *i* мы берем из списка `old`. # Вернемся к примеру с числами, введенными с клавиатуры, и попробуем получить список из чисел, используя списковые включения. # In[26]: snumbers = input("Введите числа через пробел: ") lnumbers = snumbers.split() numbers = [int(n) for n in lnumbers] # делаем все элементы целочисленными numbers # Использование списковых включений ‒ не только более компактный, но и более быстрый способ создания новых списков на основе старых. Давайте сравним время выполнения кода с циклом *for* и кода со списковыми включениями. # In[33]: get_ipython().run_cell_magic('timeit', '', '\n# timeit - магическое слово Jupyter, magic command,\n# которое позволяет измерить время исполнения ячейки с кодом\n# ячейка запускается много раз, и выводится среднее время выполнения со стандарным отклонением\n# должно быть указано первой строчкой в ячейке\n\nL = []\nfor i in range(1, 10001):\n L.append(i**2)\n') # In[34]: get_ipython().run_cell_magic('timeit', '', '\nL = [j**2 for j in range(1, 10001)]\n') # А теперь напишем компактный и быстрый код, который будет разбивать строку по запятой и при этом возвращать имена героев без лишних пробелов. # In[35]: names = input("Введите имена героев через запятую: ") lnames = names.split(",") names_final = [name.strip() for name in lnames] # берем все элементы и отсекаем пробелы names_final # готово!