Проблема с вложенным циклом for с функцией zip(), Python

#python #loops

#python #циклы

Вопрос:

У меня есть фрагмент кода, подобный этому:

 items1 = ['col1', 'col2']

items2 = ['a', 'b']
items3 = [1, 2]
data = zip(items2, items3)

for col in items1:
    print(col)
    for d in data:
        print(d)
 

и вывод:

 col1
('a', 1)
('b', 2)
col2
 

Похоже, что цикл for в «data» работает только один раз.
Мой ожидаемый результат был некоторым:

 col1
('a', 1)
('b', 2)
col2
('a', 1)
('b', 2)
 

Это работает, если я инвертирую циклы во вложенной структуре, например:

 for d in data:
    print(d)
    for col in items1:
        print(col)
 

чей вывод:

 ('a', 1)
col1
col2
('b', 2)
col1
col2
 

распечатываю всю информацию, но не сохраняю порядок, как хотелось бы.

Заранее спасибо за любое предложение, и я прошу прощения, если формат вопроса не соответствовал правилам сайта (это мой первый вопрос здесь).

Комментарии:

1. возможно, вы ищете data = list(zip(items2,items3)) zip итератор, который заканчивается после его исчерпания, он не может быть повторно использован

2. Именно поэтому вы должны вызывать zip , когда вам это нужно, а не пытаться сохранить возвращаемое значение заранее.

Ответ №1:

Большинство (если не все) итераторов могут быть пройдены только один раз. Причина, по которой это кажется запутанным, заключается в том, что вы привыкли перебирать списки, но списки не являются итераторами. Они являются итеративными, потому что вы можете получить итератор для списка. for Цикл неявно вызывает iter список, но вы можете сделать это и явно.

 itr = iter([1,2,3])  # itr is a value of type list_iterator


# Fully consumes itr, outputting
#
#   1
#   2
#   3
for x in itr:
    print(x)

# Produces no output, because there is nothing left in itr to iterate over
for x in itr:
    print(x)
 

Если вы хотите повторить результат несколько раз, вам нужно либо вызывать zip каждый раз,

 for col in items1:
    print(col)
    data = zip(items2, items3)

    for d in data:
        print(d)
 

или сначала создайте список из zip объекта.

 data = list(zip(items2, items3))
for col in items1:
    print(col)
    for d in data:
        print(d)
 

Ответ №2:

zip создает итератор. Вы используете его один раз, и он исчезнет. Вместо этого вы можете сохранить его в контейнере, таком как список, чтобы вы могли перебирать его столько раз, сколько захотите.

 items1 = ['col1', 'col2']
items2 = ['a', 'b']
items3 = [1, 2]
data = list(zip(items2, items3))

for col in items1:
    print(col)
    for d in data:
        print(d)
 

Ответ №3:

Стоит отметить, что это было одно из больших изменений между Python 2 и Python 3. В Python 2, map , zip , range , filter , keys , values , items все возвращаемые списки. В Python 3 они возвращают итераторы.

Если вы привыкли к Python 2, поначалу это может сбить с толку.