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

Do you know the difference between the following syntax?


(x for x in range(5))
tuple(range(5))

Let’s check it

4 Facts About the Lists

First off, a short review on the lists (arrays in other languages).

  • list is a type of data that can be represented as a collection of elements. Simple list looks like this –
  • lists take all possible types of data and combinations of data as their components:
>>> a = 12 >>> b = "this is text" >>> my_list = , (1, 2, 3), a] >>> print(my_list) , (1, 2, 3), 12]
  • lists can be indexed. You can get access to any individual element or group of elements using the following syntax:
& >>> a = ["red", "green", "blue"] >>> print(a) red
  • lists are mutable in Python. This means you can replace, add or remove elements.

What is List Comprehension?

Often seen as a part of functional programming in Python, list comprehensions allow you to create lists with a for loop with less code.

Let’s look at the following example.

You create a list using a for loop and a range() function.

& >>> my_list = >>> for x in range(10): ... my_list.append(x * 2) ... >>> print(my_list)

And this is how the implementation of the previous example is performed using a list comprehension:

>>> comp_list = >>> print(comp_list)

The above example is oversimplified to get the idea of syntax. The same result may be achieved simply using list(range(0, 19, 2)) function. However, you can use a more complex modifier in the first part of comprehension or add a condition that will filter the list. Something like this:

>>> comp_list = >>> print(comp_list)

Another available option is to use list comprehension to combine several lists and create a list of lists. At first glance, the syntax seems to be complicated. It may help to think of lists as an outer and inner sequences.

It’s time to show the power of list comprehensions when you want to create a list of lists by combining two existing lists.

>>> nums = >>> letters = ["A", "B", "C", "D", "E"] >>> nums_letters = [ for n in nums for l in letters] #the comprehensions list combines two simple lists in a complex list of lists. >>> print(nums_letters) >>> print(nums_letters) [, , , , , , , , , , , , , , , , , , , , , , , , ] >>>

Let’s try it with text or it’s correct to say string object.

>>> iter_string = "some text" >>> comp_list = >>> print(comp_list) ["s", "o", "m", "e", "t", "e", "x", "t"]

The comprehensions are not limited to lists. You can create dicts and sets comprehensions as well.

>>> dict_comp = {x:chr(65+x) for x in range(1, 11)} >>> type(dict_comp) >>> print(dict_comp) {1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H", 8: "I", 9: "J", 10: "K"} >>> set_comp = {x ** 3 for x in range(10) if x % 2 == 0} >>> type(set_comp) >>> print(set_comp) {0, 8, 64, 512, 216}

Difference Between Iterable and Iterator

It will be easier to understand the concept of generators if you get the idea of iterables and iterators.

Iterable is a “sequence” of data, you can iterate over using a loop. The easiest visible example of iterable can be a list of integers – . However, it’s possible to iterate over other types of data like strings, dicts, tuples, sets, etc.

Basically, any object that has iter () method can be used as an iterable. You can check it using hasattr() function in the interpreter.

>>> hasattr(str, "__iter__") True >>> hasattr(bool, "__iter__") False

Iterator protocol is implemented whenever you iterate over a sequence of data. For example, when you use a for loop the following is happening on a background:

  • first iter () method is called on the object to converts it to an iterator object.
  • next () method is called on the iterator object to get the next element of the sequence.
  • StopIteration exception is raised when there are no elements left to call.
>>> simple_list = >>> my_iterator = iter(simple_list) >>> print(my_iterator) >>> next(my_iterator) 1 >>> next(my_iterator) 2 >>> next(my_iterator) 3 >>> next(my_iterator) Traceback (most recent call last): File "", line 1, in StopIteration

Generator Expressions

In Python, generators provide a convenient way to implement the iterator protocol. Generator is an iterable created using a function with a yield statement.

The main feature of generator is evaluating the elements on demand. When you call a normal function with a return statement the function is terminated whenever it encounters a return statement. In a function with a yield statement the state of the function is “saved” from the last call and can be picked up the next time you call a generator function.

>>> def my_gen(): ... for x in range(5): ... yield x

Generator expression allows creating a generator on a fly without a yield keyword. However, it doesn’t share the whole power of generator created with a yield function. The syntax and concept is similar to list comprehensions:

>>> gen_exp = (x ** 2 for x in range(10) if x % 2 == 0) >>> for x in gen_exp: ... print(x) 0 4 16 36 64

In terms of syntax, the only difference is that you use parentheses instead of square brackets. However, the type of data returned by list comprehensions and generator expressions differs.

>>> list_comp = >>> gen_exp = (x ** 2 for x in range(10) if x % 2 == 0) >>> print(list_comp) >>> print(gen_exp) at 0x7f600131c410>

The main advantage of generator over a list is that it takes much less memory. We can check how much memory is taken by both types using sys.getsizeof() method.

Note: in Python 2 using range() function can’t actually reflect the advantage in term of size, as it still keeps the whole list of elements in memory. In Python 3, however, this example is viable as the range() returns a range object.

>>> from sys import getsizeof >>> my_comp = >>> my_gen = (x * 5 for x in range(1000)) >>> getsizeof(my_comp) 9024 >>> getsizeof(my_gen) 88

We can see this difference because while `list` creating Python reserves memory for the whole list and calculates it on the spot. In case of generator, we receive only ”algorithm”/ “instructions” how to calculate that Python stores. And each time we call for generator, it will only “generate” the next element of the sequence on demand according to “instructions”.

On the other hand, generator will be slower, as every time the element of sequence is calculated and yielded, function context/state has to be saved to be picked up next time for generating next value. That “saving and loading function context/state” takes time.

Final Thoughts

The very first thing that might scare or discourage a newbie programmer is the scale of educational material. The trick here is to treat each concept as an option offered by language, you’re not expected to learn all the language concepts and modules all at once. There are always different ways to solve the same task. Take it as one more tool to get the job done.

| |

Генераторы списков (list comprehensions) позволяют быстро создать список на основе существующих списков. При помощи генератора можно построить список на основе любого итерируемого типа данных (к примеру, из строк или кортежей).

В результате цикл создаст такой же список:

["8", "h", "o", "s", "t"]

Условные выражения в генераторах списков

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

Давайте рассмотрим генератор с выражением if:

fish_tuple = ("blowfish", "clownfish", "catfish", "octopus")
fish_list =
print(fish_list)

Список использует кортеж fish_tuple в качестве основы для нового списка fish_list.

Ключевые слова for и in используются так же, как в предыдущем размере. Кроме того, генератор содержит выражение if, благодаря чему он исключает из списка строку ‘octopus’.

Запросите содержимое списка fish_list и убедитесь, что он содержит все элементы fish_tuple, кроме ‘octopus’.

["blowfish", "clownfish", "catfish"]

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

Теперь рассмотрим другой пример, в котором используются математические операции, цифры и метод range().


print(number_list)

Читайте также:

Новый список number_list будет содержать квадратичные значения каждого чётного элемента в диапазоне от 0-9. В результате получится такой список:

Давайте разберём этот пример пошагово. Если вместо x ** 2 for x использовать просто x for x, список будет выглядеть так:

number_list =
print(number_list)

После этого в генератор было добавлено условное выражение:

number_list =
print(number_list)

Выражение if исключило из списка все нечётные числа.

Теперь осталось добавить оператор, который возведёт все элементы в квадрат:

number_list =
print(number_list)

Теперь каждый элемент списка будет возведён в квадрат.

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

number_list =
print(number_list)

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

Например, надо создать список, заполненный натуральными числами до определенного числа. "Классический" способ будет выглядеть примерно так:

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

На создание списка ушло три строчки кода. Генератор же сделает это за одну:

>>> a = [ i for i in range (1 , 15 ) ] >>> a

Здесь конструкция [ i for i in range (1 , 15 ) ] является генератором списка. Вся конструкция заключается в квадратные скобки, что как бы говорит, что будет создан список. Внутри квадратных скобок можно выделить три части: 1) что делаем с элементом (в данном случае ничего не делаем, просто добавляем в список), 2) что берем (в данном случае элемент i), 3) откуда берем (здесь из объекта range). Части отделены друг от друга ключевыми словами for и in .

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

>>> a = [ 2 , -2 , 4 , -4 , 7 , 5 ] >>> b = [ i**2 for i in a] >>> b

В данном случае в генераторе списка берется каждый элемент из списка a и возводится в квадрат. Таким образом, 1) что делаем - возводим элемент в квадрат, 2) что берем - элемент, 3) откуда берем - из списка a .

>>> >>> b = [ i*a[ i] for i in a] >>> b

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

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

В этом примере генерируемый список b состоит из вложенных списков. Если бы в генераторе были опущены квадратные скобки в выражении [ i, a[ i] ] , то произошла бы ошибка. Если все же надо получить одноуровневый список из ключей и значений словаря, надо взять каждый вложенный список и из него взять каждый элемент. Это достигается за счет вложенной конструкции for , что демонстрируется в строчке c = [ j for i in b for j in i] . "Классический" синтаксис для заполнения списка c выглядел бы так:

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

В конец генератора можно добавлять конструкцию if . Например, надо из строки извлечь все цифры:) if i%30 == 0 or i%31 == 0 ] >>> 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.

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

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 !