Для получения списка из генератора есть несколько основных способов:
Самый простой и питонический метод — передать генератор в функцию list()
:
def number_generator(n):
for i in range(n):
yield i
gen = number_generator(5)
result_list = list(gen) # Преобразование генератора в список
print(result_list) # [0, 1, 2, 3, 4]
Особенности:
Можно использовать оператор *
для распаковки генератора:
gen = (x for x in range(3))
result_list = [*gen] # Распаковка генератора в список
print(result_list) # [0, 1, 2]
Когда использовать:
Если генераторное выражение можно переписать как list comprehension:
gen = (x**2 for x in range(5))
# Эквивалентная запись:
result_list = [x**2 for x in range(5)]
print(result_list) # [0, 1, 4, 9, 16]
Плюсы:
Теоретически можно вручную перебрать генератор:
gen = (x for x in 'abc')
result_list = []
for item in gen:
result_list.append(item)
print(result_list) # ['a', 'b', 'c']
Минусы:
list()
Генераторы одноразовые:
gen = (x for x in range(3))
list1 = list(gen) # [0, 1, 2]
list2 = list(gen) # [] (генератор уже исчерпан)
Бесконечные генераторы могут привести к проблемам:
def infinite():
i = 0
while True:
yield i
i += 1
# list(infinite()) # Бесконечный цикл!
Потребление памяти — большие генераторы создадут большие списки:
# Будьте осторожны с очень большими генераторами
# big_list = list(huge_generator()) # Может исчерпать память
from itertools import islice
gen = (x for x in range(1000000))
first_100 = list(islice(gen, 100)) # Только первые 100 элементов
gen = (x for x in range(10))
filtered_list = [x for x in gen if x % 2 == 0] # [0, 2, 4, 6, 8]
Если нужно сохранить и генератор, и список:
gen = (x for x in range(3))
items = list(gen) # Создаем список
new_gen = (x for x in items) # Новый генератор из списка
Основные способы преобразования генератора в список:
list(generator)
— предпочтительный стандартный способ[*generator]
— альтернатива через распаковкуВсегда помните:
islice