Левая часть присваивания с бесконечными образующими

Извините, что удваиваю свой предыдущий вопрос, но я подумал спросить конкретные данные, которые решат проблему. Я хочу этот результат

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
"""

person Tony Veijalainen    schedule 17.10.2010    source источник


Ответы (1)


Зная длину var_list, вы можете использовать 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]
person kennytm    schedule 17.10.2010
comment
О, похоже, я должен сказать, что нужно использовать psyco и Python 2 unicode и двигаться дальше! Но как насчет среза слева? my_slice[a:b:c], *_? Я получаю неверный синтаксис. - person Tony Veijalainen; 17.10.2010
comment
@Tony: Для этого нужно использовать islice (работает и для Python 2.x). - person kennytm; 17.10.2010
comment
Количество значений заранее не известно, потому что оно динамическое по переменным. - person Tony Veijalainen; 17.10.2010
comment
@Tony: Количество значений можно легко вычислить, если это срез. Какая актуальная проблема? - person kennytm; 17.10.2010
comment
Скорость, но, конечно, варианты использования не столь серьезны (поскольку существуют лучшие решения с модулем numpy) stackoverflow.com/questions/3324947/, stackoverflow.com/questions/3285443/ - person Tony Veijalainen; 17.10.2010
comment
@Tony: Извините, вы не можете использовать *_ для бесконечных генераторов, потому что _ не является особенным, поэтому Python попытается присвоить бесконечный список _. Вам нужно использовать islice. - person kennytm; 17.10.2010