目录
Get the first N elements of a Generator in Python
在 Python 中获取生成器的前 N 个元素
获取生成器的前 N 个元素:
- 使用该
islice()
方法获取前 N 个元素的迭代器。 - 可选择将迭代器转换为列表。
from itertools import islice def g(): yield 1 yield 2 yield 3 gen = g() first_2 = list(islice(gen, 2)) print(first_2) # 👉️ [1, 2]
如果您需要从生成器中获取单个元素,请单击以下子标题。
itertools.islice
方法采用迭代器和可选的索引。start
stop
stop
我们只为的索引指定了一个值2
,因此迭代器对象只包含生成器的前 2 个元素。
该方法返回一个迭代器,但如果需要将结果转换为列表对象,则islice()
可以使用该类。list()
如果您的生成器对象不是无限长,您可以将其转换为列表并使用列表切片来获取前 N 个元素。
def g(): yield 1 yield 2 yield 3 gen = g() my_list = list(gen) first_2 = my_list[:2] print(first_2) # 👉️ [1, 2]
列表类接受一个可迭代对象并返回一个列表对象。
列表切片的语法是my_list[start:stop:step]
.
索引start
是包含的,stop
索引是排他的(最多,但不包括)。
Python 索引是从零开始的,因此列表中的第一项的索引为0
,最后一项的索引为-1
或len(my_list) - 1
。
我们只为索引指定了一个值stop
,因此列表切片从 index 开始0
并上升到,但不包括 index 2
。
或者,您可以使用该next()
功能。
使用 next() 获取生成器的前 N 个元素
这是一个三步过程:
- 使用列表理解迭代
range
长度为 N 的对象。 - 使用该
next()
函数返回每个项目。 - 新列表将只包含生成器的前 N 个元素。
def g(): yield 1 yield 2 yield 3 gen = g() first_2 = [next(gen, None) for _ in range(2)] print(first_2) # 👉️ [1, 2]
我们使用该类range()
创建了一个range
长度为 N 的对象。
print(list(range(2))) # 👉️ [0, 1] print(list(range(3))) # 👉️ [0, 1, 2]
在每次迭代中,我们使用该next()
函数从生成器中获取一个项目并返回结果。
next ()函数从提供的迭代器返回下一个项目。
该函数可以传递一个默认值作为第二个参数。
如果迭代器耗尽或为空,则返回默认值。
StopIteration
我们用作None
默认值。如果您需要None
从列表中过滤掉任何值,请使用列表理解。
def g(): yield 1 yield 2 yield 3 gen = g() # 👇️ get first 2 elements of generator next(gen) next(gen) first_2 = [next(gen, None) for _ in range(2)] print(first_2) # 👉️ [3, None] # 👇️ remove None values from the list first_2 = [item for item in first_2 if item is not None] print(first_2) # 👉️ [3]
或者,您可以使用for
循环。
使用 for 循环获取生成器的前 N 个元素
这是一个三步过程:
- 使用
for
循环迭代生成器enumerate()
。 - 检查当前索引是否小于 N。
- 如果满足条件,则将当前项目追加到列表中。
def g(): yield 1 yield 2 yield 3 gen = g() first_2 = [] for index, item in enumerate(gen): if index < 2: first_2.append(item) else: break print(first_2)
我们使用该enumerate()
函数来访问当前迭代的索引。
enumerate
函数接受一个可迭代对象并返回一个包含元组的枚举对象,其中第一个元素是索引,第二个元素是相应的项目。
my_list = ['bobby', 'hadz', 'com'] for index, item in enumerate(my_list): print(index, item) # 👉️ 0 bobby, 1 hadz, 2 com
在每次迭代中,我们检查当前索引是否小于2
。
如果满足条件,我们将该项目附加到列表中。
如果不满足条件,我们退出循环。
break
语句跳出最内层的封闭或for
循环while
。
您选择哪种方法是个人喜好的问题。如果生成器不是无限长,我会简单地将其转换为列表并使用列表切片。
在 Python 中从生成器获取单个元素
使用该next()
函数从生成器中获取单个元素。
def g(): yield 1 yield 2 yield 3 gen = g() print(next(gen)) # 👉️ 1 print(next(gen)) # 👉️ 2 print(next(gen)) # 👉️ 3 print(next(gen, None)) # 👉️ None
您可以通过调用函数一次来获取生成器的第一个元素next()
。
next ()函数从提供的迭代器返回下一个项目。
该函数可以传递一个默认值作为第二个参数。
如果迭代器耗尽或为空,则返回默认值。
StopIteration
我们使用None
默认值,但您可以使用适合您的用例的任何其他值。
def g(): yield 1 yield 2 yield 3 gen = g() print(next(gen, None)) # 👉️ 1 print(next(gen, None)) # 👉️ 2 print(next(gen, None)) # 👉️ 3 print(next(gen, None)) # 👉️ None
您还可以使用该类list()
将生成器对象转换为列表并一次获取一个元素。
def g(): yield 1 yield 2 yield 3 gen = g() my_list = list(gen) print(my_list) print(my_list[0]) # 👉️ 1 print(my_list[1]) # 👉️ 2 print(my_list[2]) # 👉️ 3 print(list(gen)) # 👉️ []
generator
列表对象是可订阅的,因此我们可以在将对象转换为列表后访问特定索引处的元素。
您还可以使用简单的循环遍历生成器对象for
。
def g(): yield 1 yield 2 yield 3 gen = g() for item in gen: print(item) # 👉️ 1, 2, 3
如果将生成器转换为列表,请确保您正在访问的索引存在。
尝试在不存在的索引处访问列表会引发IndexError
异常。
try/except
如果需要处理异常,可以使用语句。
def g(): yield 1 yield 2 yield 3 gen = g() my_list = list(gen) print(my_list) # 👉️ [1, 2, 3] try: result = my_list[100] print(result) except IndexError: # 👇️ this runs print('List index out of range')
指定的索引超出范围,因此except
块运行。
在 Python 中获取生成器的第 N 个元素
要获取生成器的第 N 个元素:
- 使用该
islice()
方法获取从索引 N 开始的迭代器。 - 将迭代器传递给
next()
函数。 - 该
next()
函数将返回生成器的第 N 个元素。
from itertools import islice def g(): yield 1 yield 2 yield 3 gen = g() second = next( islice(gen, 1, None), None ) print(second) # 👉️ 2
itertools.islice
方法采用迭代器和可选的索引。start
stop
我们使用了 的开始索引0
和 的停止索引None
。
当stop
是 时None
,则迭代继续进行,直到迭代器耗尽。
对于无限长的生成器,迭代在指定位置停止。
next ()函数从提供的迭代器返回下一个项目。
该函数可以传递一个默认值作为第二个参数。
如果迭代器耗尽或为空,则返回默认值。
如果迭代器耗尽或为空且未提供默认值,
StopIteration
则会引发异常。
None
默认值,但您可以使用适合您的用例的任何其他值。from itertools import islice def g(): yield 1 yield 2 yield 3 gen = g() item = next( islice(gen, 100, None), 'default value' ) print(item) # 👉️ default value
如果您的生成器对象不是无限长,您可以将其转换为列表并访问索引 N 处的列表元素。
def g(): yield 1 yield 2 yield 3 gen = g() my_list = list(gen) print(my_list[0]) # 👉️ 1 print(my_list[1]) # 👉️ 2 print(my_list[2]) # 👉️ 3 print(list(gen)) # 👉️ []
列表类接受一个可迭代对象并返回一个列表对象。
您还可以使用该enumerate()
函数来访问当前迭代的索引。
def g(): yield 1 yield 2 yield 3 gen = g() nthElement = next( (item for index, item in enumerate(gen) if index == 1), None ) print(nthElement) # 👉️ 2
enumerate
函数接受一个可迭代对象并返回一个包含元组的枚举对象,其中第一个元素是索引,第二个元素是相应的项目。
在每次迭代中,我们检查当前索引是否等于特定索引。
如果满足条件,我们返回相应的项目。
您选择哪种方法是个人喜好的问题。我会将该类用于list()
非无限generator
对象,因为转换为列表非常直观且可读。