【发布时间】:2021-10-29 13:34:29
【问题描述】:
我试图弄清楚迭代器如何与这个例子一起工作:
有一个函数为给定的可迭代对象(列表、生成器等)生成流生成器,其元素包含位置和值,并按外观顺序排序。 流生成器等于初始流(无位置),间隙用零填充。
from itertools import count
def gen_stream(total, sorted_iterable, extractor=lambda x: x):
sorted_iterator = iter(sorted_iterable)
iterable = count() if total is None else range(total)
try:
current_extracted_record = extractor(next(sorted_iterator))
except StopIteration:
current_extracted_record = None
for i in iterable:
if current_extracted_record:
if i == current_extracted_record[0]:
try:
yield current_extracted_record[1]
current_extracted_record = extractor(next(sorted_iterator))
except StopIteration:
current_extracted_record = None
else:
yield 0
else:
yield 0
例如:
gen = gen_stream(9,[(4,111),(7,12)])
list(gen)
[0, 0, 0, 0, 111, 0, 0, 12, 0] # first element has zero index, so 111 located on fifth position, 12 located on 8th position
此功能还支持自定义位置值提取器,用于更高级的情况,例如
def day_extractor(x):
months = [31, 28, 31, 30, 31, 31, 30, 31, 30, 31, 30, 31]
acc = sum(months[:x[1] - 1]) + x[0] - 1
return acc, x[2]
precipitation_days = [(3,1,4),(5,2,6)]
list(gen_stream(59,precipitation_days,day_extractor)) #59: January and February to limit output
[0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
precipitation_days 格式如下:(d,m,mm),其中 d - 月中的天数,m - 月,mm - 降水量,以毫米为单位 因此,例如:
(3,1,4) # January,3 precipitation: 4 mm
(5,2,6) # February,5 precipitation: 6 mm
提取器作为带有默认值的可选第三个参数传递 - 处理(位置,值)对的 lambda 函数,如第一个示例中所示。
问题从这里开始
问题 1 可以换吗
try:
current_extracted_record = extractor(next(sorted_iterator))
except StopIteration:
current_extracted_record = None
使用函数next的默认值,而不是使用一行代码捕获异常StopIteration
current_extracted_record = extractor(next((sorted_iterator), None))
在其他情况下它是否总是能正常工作?
问题2如何通过使用next()方法的默认值和循环while而不是循环为。理论上,代码应该更短。
for i in iterable:
if current_extracted_record:
if i == current_extracted_record[0]:
try:
yield current_extracted_record[1]
current_extracted_record = extractor(next(sorted_iterator))
except StopIteration:
current_extracted_record = None
else:
yield 0
else:
yield 0
问题 3 这似乎是一个愚蠢的问题,但据我了解,提取器没有索引。那么方括号中的数字是什么意思呢?
current_extracted_record[0]
current_extracted_record[1]
如果你能帮忙,谢谢。
对于线程中的 3 个问题,我深表歉意,但在我看来,它们以不同的细节描述了同一个问题。
答案(问题 1 和问题 2)
def gen_stream(total, sorted_iterable, extractor=lambda x: x):
elem_iter = iter(map(extractor, sorted_iterable))
pos, val = next(elem_iter, (None, None))
cnt = 0
while total is None or cnt < total:
if cnt == pos:
yield val
pos, val = next(elem_iter, (None, None))
else:
yield 0
cnt += 1
【问题讨论】:
-
这里的每个问题都应该关注一个问题/问题,而不是问题列表。
-
@Prophet 抱歉,问题 1 和问题 2 几乎相同。问题 3 只是对第二个问题的解释。我同意问题 4 - 它是分开的。我应该删除它吗?
-
我不是这里的版主,但是这个问题可能会因此而被简单地关闭。做什么由你决定
标签: python function loops iterator generator