- Цикл for в одну строку
- Что это за зверь?
- Создание спискового включения
- Хорошо, отлично, но зачем мне это нужно?
- Применяем условие if в список
- Примеры
- Итоги
- Больше примеров
- Как вывести цикл в одну строку питон
- Однострочный for на Python: списковое включение и генераторные выражения
- Списковое включение
- Пример
- Генератор словарей
- Пример
- Генератор множеств
- Пример
- Генераторные выражения
- Пример
- Генератор кортежей
- Когда включения не подходят?
- Производительность генераторных выражений
- Выводы
Цикл for в одну строку
Как и большинство программистов, вы знаете, что после создания массива, вам нужно написать цикл для его обработки. С этим нет никаких проблем, но иногда нам не нужно использовать несколько строк для написания полного цикла for для одной простой задачи. К частью, Python это понимает и предоставляет замечательный инструмент для использования в таких ситуациях. Этот инструмент называется генератор списка (list comprehensions, списковое включение).
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Что это за зверь?
Списковое включение (List comprehensions) – это списки, которые генерируются с циклом for внутри. Они очень распространены в Python и выглядят примерно следующим образом:
Возможно, вы еще сильнее запутались, так что сделаем шаг назад. Список содержит в себе множество вещей, но определяется между квадратными скобками. Скажем, мне нужно получить функцию, которая удваивает значения всех чисел в списке. Для начала, мне нужно создать список чисел.
Теперь создадим функцию. Назовем ее list_doubler , так как это именно то, что она делает, и она будет принимать аргумент, который является списком, который мы будем удваивать.
Вызов этой функции даст нам новый список с удвоенными элементами.
my_doubled_list теперь содержит значения 42 , 4 и 186 . Эта функция простая и делает то, что нам нужно простым способом, но это пять строк, учитывая определяющую строку. Также есть переменная, с которой мы ничего не делаем, кроме как добавляем и в конце возвращаем её.
Единственная часть функции, которая по-настоящему работает – это цикл for. Цикл for тоже мало что делает, просто умножает число на 2. Это идеальный кандидат для превращения в списковое включение.
Создание спискового включения
Давайте сохраним его как функцию, которую мы будем вызывать. Нам нужно только упростить тело функции. Так как списковое включение создает списки, а списки могут быть назначены к переменным, примем это во внимание и расположим списковое включение справа от doubled и продолжим.
Хорошо, теперь нам нужно заполнить правую сторону. Как и с нормальным циклом for, а правая часть списка выглядит именно так, нам нужно назвать элементы в нашем цикле. Сначала, назовем каждый объект, и мы также будем использовать переменную списка, которая будет передана.
Это не может работать в полной мере, так как элемент не является… элементом. В нашей изначальной функции мы выполнили num * 2 , так что давайте сделаем это еще раз.
Все что находится перед циклом for точно внесено в список. Наконец, нам нужно вернуть наш новый список.
Запускаем нашу новую функцию.
И да, my_doubled_list содержит ожидаемые значения 24 , 8 и 404 . Отлично, все работает! Но так как мы создаем и моментально возвращаем переменную, давайте просто применим списковое включение напрямую.
Хорошо, отлично, но зачем мне это нужно?
Списковые включения (генератор списка, list comprehensions) отлично подходят для случаев, когда нам нужно сохранить немного места в коде. Они также удобны в случаях, когда вам просто нужно быстро обработать списки, чтобы сэкономить время над рутинной работой с этим списком.
Они также очень полезны, если вы хотите больше узнать о функциональном программировании, но эту тему мы обсудим в будущем.
Применяем условие if в список
Давайте сделаем новую функцию, которая будет давать только длинные слова из списка. Скажем, каждое слово, которое состоит более чем из 5 букв, будет считаться длинным. Для начала пропишем их вручную.
Мы создали переменную для хранения наших слов, применяем цикл над всеми словами в нашем списке, и проверяем длинну каждого слова. Если оно длиннее 5 букв, мы вносим слово в список, и затем, наконец, мы отсылаем список назад. Давайте попробуем.
long_words([‘blog’, ‘Treehouse’, ‘Python’, ‘hi’]) возвращает [‘Treehouse’, ‘Python’] . Это как раз то, чего мы и ожидали.
Хорошо, давайте перепишем это в списковое включение. Для начала, построим то, что мы и так знаем.
Это возвращает нам все слова, не только те, которые длиннее 5 букв. Мы вносим условный оператор в конец цикла for.
Итак, мы использовали всё то же условие if, но поместили его в конец спискового включения. Оно использует то же наименование переменной, которое мы используем для элементов в списке.
Хорошо, давайте опробуем эту версию long_words([‘list’, ‘comprehension’, ‘Treehouse’, ‘Ken’]) возвращает [‘comprehension’, ‘Treehouse’] .
Примеры
1. Возводим в квадрат все числа от 1 до 9. Применяем функцию range.
2. Все цифры которые делятся на 5 без остатка, в диапазоне от 0 до 100.
3. Все цифры которые делятся на 3 и 6 без остатка, в диапазоне от 0 до 50.
4. Первая буква из каждого слова предложения.
5. Заменяем букву А в каждом слове на # .
Итоги
Надеюсь это руководство помогло вам понять простой способ экономии кода , который вам нужно написать для получения конкретной готовой работы с вашими списками.
Старайтесь сохранять ваши списковые включения короткими, а условия if – простыми. Несложно разглядеть решение многих ваших проблем в списковых включениях и превратить их в огромный беспорядок.
Если это только распалило ваш аппетит, посмотрим, сможете ли вы разобраться со словарными включениями самостоятельно. Они используют конструкторы dict, , но они довольно похожи. Вы также можете проработать установочные включения. Также ознакомьтесь с функциональным программированием в Python, если считаете себя готовым.
Больше примеров
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
Как вывести цикл в одну строку питон
1) Функция print() имеет параметр end , указывающий какой символ или какую строку выводить после вывода каждого значения (по дефолту переходом на новую строку, т.е. строкой ‘\n’ ). Укажите необходимый разделитель (например пробельной строкой ‘ ‘ ):
for x in range(0, 5): print(x, end=' ') # => 0 1 2 3 4
2) Перед выводом данные можно агрегировать в массив, который затем методом join() соединяем и выводим одной строкой:
array = [] for x in range(0, 5): array.append(str(x)) # => [0, 1, 2, 3, 4] print(' '.join(array)) # => 0 1 2 3 4
При этом все элементы должны быть строковыми объектами, поэтому в цикле мы приводили числа к строкам str(x) .
Однострочный for на Python: списковое включение и генераторные выражения
При создании коллекций элементов на Python циклы for заменяются однострочными выражениями. Python поддерживает четыре типа особенных генераторов, называемых также включениями:
- Списковые включения (генераторысписков, Listcomps).
- Словарные включения (генераторы словарей, Dictcomps).
- Множественные включения (генераторы множеств, Setcomps).
- Генераторные выражения (GenExp).
Списковое включение
Синтаксис генератора списков устроен следующим образом:
new_list = [выражение for элемент in последовательность if условие]
Часть с условием if указывается опционально.
Пример
Давайте создадим список чисел, исключив из него все отрицательные значения — для начала решим задачу с помощью обычного цикла for :
numbers = [4, -2, 7, -4, 19] new_nums = [] for num in numbers: if num > 0: new_nums.append(num) print(new_nums)
Генератор словарей
Для быстрого, лаконичного и наглядного создания словарей язык программирования Python предлагает воспользоваться специальным сокращением для циклического перебора элементов, известным как “генератор словарей”.
Синтаксис генератора словарей устроен следующим образом:
Пример
Давайте возведем в квадрат все числовые значения словаря при помощи словарного включения:
data = squared = print(squared)
Генератор множеств
Генератор множества одновременно похож на словарное включение и на списковое включение: фигурные скобки, как у словарей, остальной синтаксис выражения — как у списков. Основное отличие генератора множеств от словарного включения заключается в том, что для генерации словаря указываются ключ и значение через двоеточие, а для генерации множества — одно только значение.
Синтаксис генератора множеств устроен следующим образом:
Пример
Давайте создадим список произвольных чисел и множество парных чисел на его основе:
numbers = [13, 21, 14, 24, 53, 62] filtered_nums = set() for num in numbers: if num % 2 == 0: filtered_nums.add(num) print(filtered_nums)
При помощи генератора множеств подобная программа пишется в одну строчку:
filtered_nums = for num in numbers if num % 2 == 0> print(filtered_nums)
Генераторные выражения
Подобно включениям, выражение генератора предлагает сокращенный синтаксис для цикла for .
Синтаксис генераторных выражений следующий:
( выражение for элемент in последовательность if условие )
Пример
Давайте возведем в квадрат все четные числа списка и отбросим все нечетные.
Для начала решим задачу с помощью обычного цикла for :
def square_even(numbers): for number in numbers: if number % 2 == 0: yield(number * number) numbers = [1, 2, 3, 4, 5, 6] squared_numbers = square_even(numbers) for number in squared_numbers: print(number)
С помощью выражения-генератора можно вообще забыть о потребности в функции square_even() и сделать то же самое с помощью одной строки кода:
squared_numbers = (num * num for num in numbers if num % 2 == 0) for number in squared_numbers: print(number)
Генератор кортежей
При взгляде на синтаксис генераторных выражений, сразу же в голову приходит мысль: как написать кортежное включение?
Генераторное выражение можно передавать в качестве параметра любой функции-конструктору стандартных типов данных Python:
tuple(выражение for элемент in последовательность if условие)
Когда включения не подходят?
Только что вы узнали о четырех типах генераторов последовательностей в Python.
Теперь важно научиться избегать соблазна заменить все циклы for в ваших проектах на включения: давайте обсудим, в каких случаях генераторы последовательностей не подходят.
Короче говоря, не используйте включения, когда они снижают качество вашего кода!
Хороший пример — это работа со вложенными циклами for . Если написать вложенный цикл for в виде включения, то код станет короче на несколько строк, но его качество рискует ухудшиться.
Давайте рассмотрим матрицу; она часто представляется в Python как список из списков. Если вы хотите отобразить матрицу в одном измерении, то можете применить двойное списковое включение:
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ] flat_matrix = [num for row in matrix for num in row] print(flat_matrix)
Код лаконичен, но, возможно, не так интуитивно понятно, что он делает: если вместо включения написать вложенный цикл for, то программа сразу станет более понятным:
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ] flat_matrix = [] for row in matrix: for num in row: flat_matrix.append(num) print(flat_matrix)
Производительность генераторных выражений
Наконец, давайте посмотрим на производительность включений в сравнении с обычным циклом for :
Аналогичный бенчмарк для генераторов множеств и словарей дает схожие результаты: включение работает немного быстрей.
Для генераторных выражений сравнение с циклом for + yield бессмысленно: оба возвращают объект-генератор почти мгновенно. Время не тратится на вычисление значений, поскольку генераторы не хранят значения.
Следовательно, не стоит универсально везде применять включения для повышения производительности программ. Выигрыш в скорости выполнения незначителен по сравнению с вредом, наносимым длинными и многословными включениями. Применяйте генераторы последовательностей только тогда, когда это очистит ваш код без снижения его качества.
Выводы
Включения превращают циклы for в однострочные выражения.
Python поддерживает четыре вида включений для стандартных структур данных:
- Списковые включения.
- Словарные включения.
- Множественные включения.
- Генераторные выражения.
Разумное применение включений улучшает качество вашего кода, но откажитесь от слепой замены всех циклов на выражения, ведь иногда замена вложенного цикла for на включение снижает понятность кода.
Включения выполняются быстрее, чем цикл for , однако разница — всего 10%, поэтому вместо производительности отдавайте предпочтение качеству кода.
Спасибо за прочтение, счастливого программирования!