DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on

Iterator in Python (3)

Buy Me a Coffee

*Memo:

A generator can create an iterator as shown below:

def gen():
    yield 0
    yield 1
    yield from [2, 3, 4]

print(gen)       # <function func at 0x000001FCD2E3CAE0>
print(type(gen)) # <class 'function'>

v = gen()

print(v)       # <generator object func at 0x00000282207E3CC0>
print(type(v)) # <class 'generator'>

for x in v:
    print(x)
# 0
# 1
# 2
# 3
# 4
Enter fullscreen mode Exit fullscreen mode

A generator comprehension can create a generator's iterator as shown below:

<1D iterator>:

v = (x**2 for x in [0, 1, 2, 3, 4, 5, 6, 7])

for x in v:
    print(x)
# 0
# 1
# 4
# 9
# 16
# 25
# 36
# 49
Enter fullscreen mode Exit fullscreen mode

<2D iterator>:

sample = [[0, 1, 2, 3], [4, 5, 6, 7]]

v = ((y**2 for y in x) for x in sample)

for x in v:
    for y in x:
        print(y)
# 0
# 1
# 4
# 9
# 16
# 25
# 36
# 49
Enter fullscreen mode Exit fullscreen mode

<3D iterator>:

sample = [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]

v = (((z**2 for z in y) for y in x) for x in sample)

for x in v:
    for y in x:
        for z in y:
            print(z)
# 0
# 1
# 4
# 9
# 16
# 25
# 36
# 49
Enter fullscreen mode Exit fullscreen mode

Even a big iterator doesn't get MemoryError as shown below:

v = iter(range(100000000))

print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # 3
print(next(v)) # 4
# ...
Enter fullscreen mode Exit fullscreen mode
v = (x for x in range(100000000))

print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # 2
print(next(v)) # 3
print(next(v)) # 4
# ...
Enter fullscreen mode Exit fullscreen mode

An iterator cannot be read by indexing and slicing and changed by indexing, slicing and a del statement as shown below:

*Memo:

  • A del statement cannot remove zero or more elements from an iterator by indexing and slicing but can remove one or more variables themselves.
v = iter(['a', 'b', 'c', 'd', 'e', 'f'])

print(v[1], v[3:5])
# TypeError: 'list_iterator' object is not subscriptable
Enter fullscreen mode Exit fullscreen mode
v = iter(['a', 'b', 'c', 'd', 'e', 'f'])

v[1] = 'X'
v[3:5] = ['Y', 'Z']
# TypeError: 'list_iterator' object does not support item assignment
Enter fullscreen mode Exit fullscreen mode
v = iter(['a', 'b', 'c', 'd', 'e', 'f'])

del v[1], v[3:5]
# TypeError: 'list_iterator' object does not support item deletion
Enter fullscreen mode Exit fullscreen mode
v = iter(['a', 'b', 'c', 'd', 'e', 'f'])

del v

print(v)
# NameError: name 'v' is not defined
Enter fullscreen mode Exit fullscreen mode

If you really want to read and change an iterator, use list() and iter() or __iter__() as shown below:

v = iter(['a', 'b', 'c', 'd', 'e', 'f'])

v = list(v)

v[1] = 'X'
v[3:5] = ['Y', 'Z']

v = iter(v)
v = v.__iter__()

for x in v:
    print(x)
# a
# X
# c
# Y
# Z
# f
Enter fullscreen mode Exit fullscreen mode
v = iter(['a', 'b', 'c', 'd', 'e', 'f'])

v = list(v)

del v[1], v[3:5]

v = iter(v)
v = v.__iter__()

for x in v:
    print(x)
# a
# c
# d
Enter fullscreen mode Exit fullscreen mode

Top comments (0)