使用无限生成器分配的左侧

时间:2010-10-17 18:17:12

标签: python generator lazy-evaluation infinite

很抱歉将我之前的问题翻倍,但我想问一下可以解决问题的具体数据。我想要这个结果

tuple_of_vars = (item for _, item for zip(tuple_of_vars, new_vals_generator))

因为这是不可能的

a, b, c, d = (val for val in infite_generator)

实际上我想用单行做

for var in var_list:
    var = next(infinite_generator)

是否有任何解释器钩子可以在分配的左侧获取变量数量的元信息?更好的是,我可以自动执行最后一段代码(包括左侧的情况,即带有可变索引和步骤的切片)

还有一种方法可以生成变量的生成器,这些变量将在赋值的左侧。

编辑:这不会在Python3中停止:

def incr(a):
    while True:
        yield a
        a += 1


a = [None for i in range(20)]

a[3:3:3], *_ = incr(1)

print(a)

同样:

a,b,c,d, *_ = incr(1)

print(a, b, c, d)

即使它没有切片(实际上索引也是变量,这只是测试)。我知道islice等,但它太慢了。

这也产生错误:

a = 1000*[True]

bound = int(len(a) ** 0.5)

for i in range(3, bound, 2):
    a[3::i], *x = [[False] for _ in range(bound)]

""" Error:
ValueError: attempt to assign sequence of size 1 to extended slice of size 333
"""

而且:

a = 1000*[True]

bound = int(len(a) ** 0.5)

for i in range(3, bound, 2):
    a[3::i], *x = [False] * bound

""" Error:
TypeError: must assign iterable to extended slice
"""

1 个答案:

答案 0 :(得分:1)

当你知道var_list的长度时,你可以use itertools.islice切断无限生成器:

>>> import itertools
>>> infgen = itertools.cycle([1,4,9])
>>> a,b,c,d = itertools.islice(infgen, 4)
>>> a,b,c,d
(1, 4, 9, 1)

它也适用于分配一个列表。

>>> lst = [0]*20
>>> lst[2:10:2] = itertools.islice(infgen, 4)
>>> lst
[0, 0, 4, 0, 9, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]