## 复现 bug¶

In [1]:
def print_iterator(iterator):
while True:
try:
element = next(iterator)
except StopIteration:
break
else:
print(element)


In [3]:
print_iterator(iter([1, 2, 3]))

1
2
3


### counter_iterable¶

In [7]:
def counter_iterable(iterable):
iterator = iter(iterable)
iterator_length = sum(1 for _ in iterator)

print(iterator_length)


In [6]:
counter_iterable([1, 2, 3])

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-6-34aa9b80fd4b> in <module>()
----> 1 counter_iterable([1, 2, 3])

NameError: name 'counter_iterable' is not defined

### 组合在一起¶

In [9]:
def counter_iterable_and_print(iterable):
iterator = iter(iterable)
iterator_length = sum(1 for _ in iterator)

print(iterator_length)

print_iterator(iterator)


In [10]:
counter_iterable_and_print([1, 2, 3])

3


## 原因¶

iterator 内有有状态信息，具有不可重入（non-reentrant）的特性，这个和 list, tuple, dict 等容器不一样，容器通过 __getitem__ 来迭代。

In [12]:
iterable = [1, 2, 3]
iterator = iter(iterable)
iterator_length = sum(1 for _ in iterator)
iterator_length_2 = sum(1 for _ in iterator)

In [13]:
print(iterator_length)
print(iterator_length_2)

3
0


## 解决方案¶

In [14]:
iterable = [1, 2, 3]

iterator = iter(iterable)
iterator_length = sum(1 for _ in iterable)

iterator = iter(iterable)
iterator_length_2 = sum(1 for _ in iterable)

In [15]:
print(iterator_length)
print(iterator_length_2)

3
3