Генераторы списков, словарей и множеств. Генератор списка Генераторы питон

Представим себе ситуацию - вам необходимо извлечь все элементы списка и присвоить каждый из них своей определенной переменной. Например, у нас есть список описывающий человека и содержащий следующие элементы:

Person_data = ["John", "Smith", 23, "programmer"]

User_name, user_surname, user_age, user_occupation = person_data

После этого мы сможем использовать отдельно каждую созданную переменную.

Обратите внимание, что количество создаваемых переменных должно соответствовать количеству элементов в списке, иначе вы получите ошибку.

Как пользоваться генераторами в Python.

Генераторами списков в Python называются однострочные конструкции, которые позволяют создавать новые списки.

Синтаксис генераторов списков такой:

# самый простой генератор new_list =

В итоге new_list будет содержать числа от 0 до 9. Понятно, что для того чтобы создать такой список незачем пользоваться генератором. Достаточно просто воспользоваться функцией range()

# пример посложнее word = "hello" new_list =

Теперь new_list будет выглядеть так:

["h","e","l","l","o"]

Так же в генераторы списков можно вставлять конструкцию if:

# Создаем список из чисел кратных трем new_list =

В итоге получим:

Наконец, в генераторе можно использовать несколько списков и переменных:

# создание колоды карт при помощи генератора списков # масти suits = "HDCS" # ранги ranks = "23456789TJQKA" # генерируем колоду deck =

Получим следующий результат:

Представьте, сколько времени мы сэкономили, написав всего одну строчку вместо нескольких циклов .

Как извлечь элементы из подсписков в Python.

Так же, часто возникает ситуация, когда необходимо извлечь элементы из подспиков списка.

Например имеем такой список:

Outer = [, , ]

Задача создать отдельный список содержащий все элементы подсписков данного списка. Выполнить эту задачу можно при помощи все того же генератора списков:

New_list =

Таким образом получаем список со всеми элементами:

На этом на сегодня все. Удачи в освоении Python !

Python поддерживает концепцию, называемую "list comprehensions" (генераторы списков ).

Это концепция позволяет создавать списки очень естественным, лёгким способом, подобно тому как это делают математики.

Ниже обычные способы описание списков (или коллекций, или кортежей, или векторов) в математике:

S = {x 2: x in {0 ... 9}}
V = {1,2,4,8, ..., 2 2 }
M = {x | x in S and x even}

Вы, возможно, помните подобные вещи со школьных уроков. В Python-е вы можете писать эти же выражения почти так же как это бы сделали математики, без необходимости запоминать особый синтаксис.

Как наши выражения выглядят в Python-е:

>>> S = >>> V = >>> M = >>> >>> print S; print V; print M
Уверен, что вы хотите видеть более сложный пример. :) Ниже будет представлен еще один способ нахождения простых чисел . Интересным является то, что мы сперва строим список из не простых чисел, используя первый генератор списков, а затем второй генератор списков чтобы получить "инверсию" списка, которая является простыми числами.

>>> noprimes = >>> primes = >>> print primes NB: Вы можете встраивать генераторы списков один в другой, так что могли бы в нашем примере обойтись одним единственным выражением (без необходимости использовать переменную "noprimes" для хранения промежуточных результатов). Однако, наше выражение получилось бы длинным и менее читаемым, что не рекомендуется. Конечно, генератор списков может использоваться не только для чисел. Списки могут содержать элементы любого типа, включая строки, встроенные списки и функции. Вы даже можете смешивать различные типы в одном списке.

В следующем примере мы имеем дело со списком строк и генерим список списков. Каждый из встроенных списков содержит две строки и одно целочисленное значение.

>>> words = "The quick brown fox jumps over the lazy dog".split() >>> print words ["The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] >>> stuff = [ for w in words] >>> for i in stuff: ... print i
["THE", "the", 3] ["QUICK", "quick", 5] ["BROWN", "brown", 5] ["FOX", "fox", 3] ["JUMPS", "jumps", 5] ["OVER", "over", 4] ["THE", "the", 3] ["LAZY", "lazy", 4] ["DOG", "dog", 3] >>> stuff = map(lambda w: , words) >>> for i in stuff: ... print i ["THE", "the", 3] ["QUICK", "quick", 5] ["BROWN", "brown", 5] ["FOX", "fox", 3] ["JUMPS", "jumps", 5] ["OVER", "over", 4] ["THE", "the", 3] ["LAZY", "lazy", 4] ["DOG", "dog", 3]
В примере выше демонстрируется, что вы реализовывать нашу задачу двумя способами - сперва используя генератор списков, а затем используя map() и lambda функцию. Однако есть случаи, когда вы не можете использовать map() и должны применять генаротор списков, и наоборот. Если применимы два способа, то зачастую лучше пользоваться генератором списков, потому что он более эффективный и более читаемый, в большинстве случаев.

Вы не можете использовать генераторы списков, когда условие составления является слишком сложным, чтобы быть выраженным оперраторами "for" и "if" или же когда условие меняется динамически во время работы программы. В этом случае лучше использовать map() и/или filter() с подходящей функцией. Конечно, вы можете комбинировать их с герератором списков.

Оригинальная статья:

В Python просто генераторы и генераторы списков - разные вещи. Здесь есть проблема перевода с английского. То, что мы привыкли называть генератором списка, в английском варианте звучит как "list comprehension " и к генераторам никакого отношения не имеет.

Слово "comprehension" (понимание, осмысление) оказывается как бы не в тему при переводе на русский. Получается что-то вроде "понимание списка". Поэтому мы говорим "генератор списка", понимая под словом "генератор" не объект, а синтаксическую конструкцию, которая генерирует, то есть создает, список.

С другой стороны, объекты-генераторы - это особые объекты-функции, которые между вызовами сохраняют свое состояние. В цикле for они ведут себя подобно итерируемым объектам, к которым относятся списки, словари, строки и др. Однако генераторы поддерживают метод __next__(), а значит являются разновидностью итераторов.

Быстрым способом создания относительно простых объектов-генераторов являются генераторные выражения - generator expressions . Синтаксис этих выражений похож на синтаксис генераторов списков. Однако они возвращают разные типы объектов. Первый - объект-генератор. Второй - список.

Сначала рассмотрим генераторы списков, чтобы привыкнуть к синтаксической конструкции.

Генераторы списков

В Python генераторы списков позволяют создавать и быстро заполнять списки.

Синтаксическая конструкция генератора списка предполагает наличие итерируемого объекта или итератора, на базе которого будет создаваться новый список, а также выражение, которое будет что-то делать с извлеченными из последовательности элементами перед тем как добавить их в формируемый список.

>>> a = [ 1 , 2 , 3 ] >>> b = [ i+10 for i in a] >>> a [ 1 , 2 , 3 ] >>> b [ 11 , 12 , 13 ]

В примере выше генератором списка является выражение . Здесь a - итерируемый объект. В данном случае это другой список. Из него извлекается каждый элемент в цикле for. Перед for описывается действие, которое выполняется над элементом перед его добавлением в новый список.

Обратите внимание, что генератор создает новый список, а не изменяет существующий. Если надо изменить текущую переменную, ей надо присвоить новое значение:

>>> a = [ 1 , 2 , 3 ] >>> a = [ i+10 for i in a] >>> a [ 11 , 12 , 13 ]

Генераторы списков относятся к разряду "синтаксического сахара" языка программирования Python. Другими словами, без них можно обойтись:

>>> for index, value in enumerate (a) : ... a [ index] = value + 10 ... >>> a [ 11 , 12 , 13 ]

Если в программе может быть несколько ссылок на список, генераторами надо пользоваться осторожно:

>>> ls0 = [ 1 , 2 , 3 ] >>> ls1 = ls0 >>> ls1.append (4 ) >>> ls0 [ 1 , 2 , 3 , 4 ] >>> ls1 = [ i+1 for i in ls1] >>> ls1 [ 2 , 3 , 4 , 5 ] >>> ls0 [ 1 , 2 , 3 , 4 ]

Здесь мы предполагаем, что изменение списка через одну переменную, будут видны через другую. Однако если изменить список генератором, то переменные будут указывать на разные списки.

Перебираемым в цикле for объектом может быть быть не только список. В примере ниже в список помещаются строки файла.

>>> lines = [ line.strip () for line in open ("text.txt" ) ] >>> lines [ "one" , "two" , "three" ]

В генератор списка можно добавить условие:

>>> from random import randint >>> nums = [ randint(10 , 20 ) for i in range (10 ) ] >>> nums [ 18 , 17 , 11 , 11 , 15 , 18 , 11 , 20 , 10 , 19 ] >>> nums = [ i for i in nums if i%2 == 0 ] >>> nums [ 18 , 18 , 20 , 10 ]

Генераторы списков могут содержать вложенные циклы:

>>> a = "12" >>> b = "3" >>> c = "456" >>> comb = [ i+j+k for i in a for j in b for k in c] >>> comb [ "134" , "135" , "136" , "234" , "235" , "236" ]

Генераторы словарей и множеств

Если в выражении генератора списка заменить квадратные скобки на фигурные, то можно получить не список, а словарь:

>>> a = { i:i**2 for i in range (11 , 15 ) } >>> a { 11 : 121 , 12 : 144 , 13 : 169 , 14 : 196 }

При этом синтаксис выражения до for должен быть соответствующий словарю, то есть включать ключ и через двоеточие значение. Если этого нет, будет сгенерировано множество:

>>> a = { i for i in range (11 , 15 ) } >>> a set ([ 11 , 12 , 13 , 14 ] ) >>> b = { 1 , 2 , 3 } >>> b set ([ 1 , 2 , 3 ] )

Генераторы

Выражения, создающие объекты-генераторы, похожи на выражения, генерирующие списки, словари и множества за одним исключением. Чтобы создать генераторный объект, надо использовать круглые скобки:

>>> a = (i for i in range (2 , 8 ) ) >>> a < generator object < genexpr> at 0x7efc88787910 > >>> for i in a: ... print (i) ... 2 3 4 5 6 7

Второй раз перебрать генератор в цикле for не получится, так как объект-генератор уже сгенерировал все значения по заложенной в него "формуле". Поэтому генераторы обычно используются, когда надо единожды пройтись по итерируемому объекту.

Кроме того, генераторы экономят память, так как в ней хранятся не все значения, скажем, большого списка, а только предыдущий элемент, предел и формула, по которой вычисляется следующий элемент.

Выражение, создающее генератор, это сокращенная запись следующего:

>>> def func(start, finish) : ... while start < finish: ... yield start * 0.33 ... start += 1 ... >>> a = func(1 , 4 ) >>> a < generator object func at 0x7efc88787a50 > >>> for i in a: ... print (i) ... 0.33 0.66 0.99

Если нет необходимости использовать функцию многократно, проще использовать выражение:

>>> b = (i*0.33 for i in range (1 , 4 ) ) >>> b < generator object < genexpr> at 0x7efc88787960 > >>> for i in b: ... print (i) ... 0.33 0.66 0.99

У языка программирования Pyrhon есть особая синтаксическая конструкция, с помощью которой можно на основании определенных правил создавать заполненные списки. Формируемые списки могут получаться различными, содержание конструкции может быть разным, поэтому они получили название генераторы списков. Они удобны, потому что записи получаются не такими длинными, нежели при традиционном методе создания списков.

К примеру, нужен список из натуральных чисел до конкретного числа. Традиционный метод будет иметь такой вид:

>>> a = >>> for i in range(1,15): ... a.append(i) ... >>>

Список занял три строчки кода. А генератору нужна только одна:

>>> a = >>> a

Конструкция – это генератор списка. Всю конструкции нужно поместить в квадратные списки, что отражает создание списка. Внутри скобок есть три части:

  1. Что будем делать с элементов (в нашей ситуации не делаем ничего, просто вносим в перечень).
  2. Что будем брать (мы берем элемент i).
  3. Откуда будем брать (из объекта range). Для отделения частей используем ключевые слова in и for.

Разберем на примере

>>> a = >>> b = >>> b

В этой ситуации мы берем каждый элемент перечня и возводим в квадрат. Отсюда:

  1. Делаем – возводим наш элемент в квадрат.
  2. Берем – элемент.
  3. Откуда – из перечня а.
>>> a = {1:10, 2:20, 3:30} >>> b = for i in a] >>> b

Тут берем ключ в словаре, а в генерируемый список попадает произведение ключа на имеющееся у него значение.

>>> a = {1:10, 2:20, 3:30} >>> b = [] for i in a] >>> b [, , ] >>> c = >>> c

В данном случае список b содержит вложенные списки. Опустив в генераторе квадратные скобы по выражению ] была бы получена ошибка. Если вам нужен одноуровневый перечень с ключами из словарных значений, нужно взять каждый вложенный перечень и уже оттуда брать каждый компонент. Делается это вложенной конструкцией for. Традиционный синтаксис формирования перечня имеет такой вид:

>>> c = >>> for i in b: ... for j in i: ... c.append(j) ... >>> c

Генераторы списков могут дополняться конструкцией if. К примеру, нужно извлечь все числа из строки:

>>> a = "lsj94ksd231 9" >>> b =

Либо наполнить список цифрами, кратными 31 или 30:

>>> a = >>> a

Перечни так создаваться намного проще и быстрее. Но, они не годятся для замены достаточно сложных конструкций. К примеру, если в условии проверки будет ветка else.

Закончились деньги, а до зарплаты еще пара недель? Можно одолжить, но что делать если не у кого? Не идти же в банк за кредитом. В этом случае вам помогут микрозаймы . Простой зайдите на сайт, оформите заявку (это очень просто и быстро) и через несколько минут вы получите деньги! Очень удобно и быстро, и главное не нужно ни у кого просить!

Генераторы списка в языке программирования Python являются мощным инструментом по работе с разноплановыми совокупностями данных. Чаще всего эти конструкции используются для более удобного взаимодействия со списками, обеспечивая не только их создание, но и модификацию. Несмотря на то, что в некоторых случаях без генераторов можно обойтись, их грамотное применение значительно упрощает реализацию сложных алгоритмов.

Простая генерация

Самым простым способом создания является обычное присваивание ему необходимых значений или объектов. В том случае, когда элементов последовательности немного, их можно просто перечислить один за другим. Но если их количество переваливает за десяток, следует всерьез задуматься об использовании генератора списка. Данная конструкция обеспечивает его автоматическое заполнение, исходя из определенных инструкций .

Следующий пример демонстрирует создание в Python списка чисел при помощи генератора. Переменная i является ссылкой на текущий элемент объекта data. Функция range здесь принимает два аргумента, которые устанавливают границы для сгенерированной последовательности целых чисел. Вывод информации на экран происходит через метод print.

>>> data = >>> print(data)

Генераторы списка Python 3 работают не только с численными значениями. Как показывает следующий пример, генератору можно передать в качестве аргумента строку либо ссылку на нее.

>>> data = >>> print(data) ["p", "y", "t", "h", "o", "n"]

В результате выполнения этого кода будет построен список из символов, которые включала в себя исходная строка. Как и в случае с предыдущим примером, вывести полученный набор данных на экран можно при помощи уже известного метода print.

Генератор с условием

Один из часто используемых способов генерации списков в Python - с условием. Предыдущие примеры демонстрировали довольно тривиальный подход к заполнению списка при помощи генератора. Данные конструкции языка Python позволяют задавать определенные условия для выполнения такой операции . Например, существует задача перенести в список только четные числовые значения из созданной ранее выборки range.

>>> data = >>> print(data)

В дело вступает команда if, после которой следует небольшая инструкция, сообщающая о том, что каждый элемент последовательности должен выполнять некоторое условие. В данном случае необходимо возвращать 0 в результате вычисления остатка от целочисленного деления. Как можно увидеть, прошедшие проверку цифры были занесены в список.

Генератор с циклом

В языке Python также существует возможность генерировать список при помощи нескольких циклов , помещая их в квадратные скобки инициализации. В следующем примере используется две конструкции for, осуществляющие поочередный перебор значений для переменных i и j. Числовой диапазон для них (от 0 до 3), как и раньше, задается через методы range.

>>> data = >>> print(data)

Результатом выполнения данного кода станет создание списка data на основе поочередного перемножения переменных i и j. Благодаря циклам for, их значения увеличиваются пошагово. Таким образом, генерируется список из девяти элементов.

Генерация вложенных списков

Иногда у программиста возникает необходимость в использовании списков с более чем одним измерением. К примеру, многомерные наборы данных могут понадобиться в случае работы с математическими матрицами. Для этого в Python можно также применять генераторы, просто помещая цикл для создания одного списка внутрь другого . Ограничениями области действия для вложенного списка станут квадратные скобки, как показано в следующем примере.

>>> data = [ for j in range(0, 3)] >>> print(data) [, , ]

Данный код демонстрирует создание двумерной матрицы с размерностью 3×3 при помощи генератора двумерного списка Python. Элементами этой числовой последовательности стали цифровые значения из методов range, как и в предыдущих примерах. Переменные i и j пошагово увеличиваются в циклах на единицу и перемножаются между собой. Функция print служит для визуального отображения сгенерированного набора данных на экран компьютера.

Достаточно часто при создании вложенного списка Python используется генератор матрицы нулей. В качестве примера создадим матрице 3×2:

>>> data = [ for y in range(3)] >>> print(data) [, , ]

Генератор списка с lambda

Как известно, лямбда-функции в Python представляют собой некую операцию, возвращающую значение. Преимуществом данного механизма является возможность его применения внутри выражения. Это позволяет значительно уменьшить объем набираемого программистом кода, поскольку в таком случае нет необходимости отдельно объявлять новый метод . Генератор списка с lambda в Python позволяет

Иногда используются в Python lambda-функции в генераторе списков. В следующем примере будет создана новая последовательность чисел, полученных в результате выполнения метода range. Как и раньше, элемент этого набора представляется в виде переменной i, которая пошагово получает новые значения (от 0 до 9) в цикле for. Лямбда-функция принимает в качестве аргумента значение, затем перемножает его само на себя и возвращает обратно в генератор.

>>> data = [(lambda i: i*i)(i) for i in range(0, 10)] >>> print(data)

Таким образом, создается список data, содержащий результаты возведения в квадрат для чисел от 0 до 9. Как обычно, функция print выводит информацию на экран.

Применение itertools

Для выполнения продвинутой генерации списка в языке Python используется подключаемая библиотека под названием itertools. С ее помощью можно создавать наборы значений по определенным правилам. Чтобы активировать функции данного модуля, следует внести в начало программного файла следующую инструкцию .

Import itertools

Методы, которые содержит эта библиотека, позволяют генерировать списки с использованием улучшенных циклов. Например, с ее помощью можно легко создавать комбинации различных значений, как символьных, так и числовых . Следующий код является простым примером генерации списка с вызовом функции repeat.

>>> data = >>> print(data)

Как видно из полученного результата, метод возвращает последовательность одинаковых объектов (в данном случае это число 1), повторяющихся 5 раз.

Заключение

Продвинутые функциональные возможности, представленные в языке Python генераторами списков, позволяют программисту повысить скорость и эффективность обработки данных. Рассмотренный механизм включает в себя создание как обычных, так и многомерных списков на основе определенных условий, а также с использованием циклов. Также в языке имеется возможность генерации при помощи lambda-выражений и с использованием библиотеки intertools.

Похожие публикации