4

I have these two lists

l1 = [1,2,3]
l2 = [10,20,30]

I use this nested for loop to access all possible pairs:

for a in l1:
    for b in l2:
        print(a,b)

I get the following expected result:

1 10
1 20
1 30
2 10
2 20
2 30
3 10
3 20
3 30

But if I convert l1 and l2 to iterators, I get a different result and I can't access to all of the pairs:

l1=iter(l1)
l2=iter(l2)

for a in l1:
    for b in l2:
        print(a,b)

1 10
1 20
1 30

I can't understand the difference between these two code snippets. Why the iterators generate this result?

Mahsa
  • 581
  • 1
  • 9
  • 28
  • 2
    Once you've consumed the iterator, its done. No more values for you. After the first `for b in l2:` the well is dry. – tdelaney Jun 28 '20 at 07:23
  • I know this doesn't *look* like a duplicate, but that's the closest match I can easily find for this common problem. Sequence iterators created by `iter` have the same relevant behaviour as file iterators created by `open`. – Karl Knechtel Jun 28 '20 at 07:24
  • 1
    @KarlKnechtel -Actually... files can be rewound (e.g., `file.seek(0)`). They are a counter example. `iter()` itself doesn't care which type of iterator you get. `list_iterator` can't be rewound, file can. – tdelaney Jun 28 '20 at 07:26
  • They *can*, but the point is about the specific style of iteration in play. – Karl Knechtel Jun 28 '20 at 07:27
  • @KarlKnechtel- Yes this is because reader objects are iterators, just like file object returned by open(). – Mahsa Jun 28 '20 at 08:03

1 Answers1

3
l2=iter(l2)

This creates an iterator out of l2. An iterator can only be iterated through once. After that, the interator is finished. If you wanted to iterate over l2 again, you'd need to create another iterator from it.

for a in l1:
    for b in l2:
        print(a,b)

This will try to iterate over l2 - once for each item in l1. If there are more than 1 items in l1, that won't work - because the l2 iterator is already exhausted after the first iteration.

So you need something like this:

l1 = iter(l1)

for a in l1:
    l2_iter = iter(l2)
    for b in l2_iter:
        print(a,b)

Which would do what you expect.

rdas
  • 20,604
  • 6
  • 33
  • 46