gpt4 book ai didi

python - 流生成器。详细使用迭代器

转载 作者:行者123 更新时间:2023-12-02 18:34:21 25 4
gpt4 key购买 nike

我试图弄清楚迭代器如何与此示例一起工作:

有一个函数为给定的可迭代对象(列表、生成器等)生成流生成器,其元素包含位置和值并按出现顺序排序。流生成器等于初始流(没有位置),间隙用零填充。

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

最佳答案

问题1

不,如果 next 返回 Noneextractorextractor(next(sorted_iterator, None)) 将失败无法处理它。例如,您的 day_extractor 不能(它会崩溃),并且默认身份提取器不会返回一对索引和值,因此后面代码将失败。 p>

问题2

可以通过将extractor映射到sorted_iterable并请求next值< em>那个:

def gen_stream(total, sorted_iterable, extractor=lambda x: x):
specials = map(extractor, sorted_iterable)
iterable = count() if total is None else range(total)
current_extracted_record = next(specials, None)
for i in iterable:
if current_extracted_record and i == current_extracted_record[0]:
yield current_extracted_record[1]
current_extracted_record = next(specials, None)
else:
yield 0

由于没有负索引,我们还可以使用 [-1] 代替 None 来缩短内部 if 条件(或者实际上任何 count() 中没有的内容,例如 [None])。让我也重命名一下。

def gen_stream(total, sorted_iterable, extractor=lambda x: x):
specials = map(extractor, sorted_iterable)
indexes = count() if total is None else range(total)
next_special = next(specials, [-1])
for i in indexes:
if i == next_special[0]:
yield next_special[1]
next_special = next(specials, [-1])
else:
yield 0

问题3

current_extracted_record 是提取器返回的内容,即下一个特殊(索引,值)。其中索引为 0 和 1。

关于python - 流生成器。详细使用迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68990208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com