1. The generator

This article is participating in Python Theme Month,See the event link for details

First, let’s look at iterators. An iterator is an object that enables the programmer to iterate over containers, especially lists. An iterator, however, iterates over and accesses the data elements in the container, but does not iterate. You might get confused, so let’s take it slow. Divided into three parts, respectively:

  • Can be an iterative
  • The iterator
  • The iteration

All of these parts are related to each other. We’ll discuss each of them, and we’ll talk about generators later.

1.1 Iterable

Iterable is any object in Python that defines either an __iter__ or a __getitem__ method that returns an iterator or can take an index. In short, iterable is anything that can give us an iterator. So what is an iterator?

1.2 the iterator

An iterator is any object in Python that has a next(Python2) or __next__ method defined. That’s it. That’s an iterator. Now let’s look at iteration.

1.3 iteration

Iteration, which is the process of getting data from something, such as a list. When we use a loop to loop through something, it’s called iteration. It is the name of the process itself. Now that we have a basic understanding of these terms, let’s look at generators.

1.4 the generator

Generators are iterators, but you can only iterate over them once. This is because they do not store all values in memory, but instead generate them instantly. You can use them by iterating over them, by using a “for” loop, or by passing them to any iterated function or construct. Generators are implemented as functions most of the time. However, they don’t return, they use yield. Here is a simple example of a generator function:

def generator_function() :
    for i in range(10) :yield i

for item in generator_function():
    print(item)

# Output: 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
Copy the code

It’s not very useful in this case. Generators are best suited to compute a large number of results (especially those involving the loop itself), and you don’t want to allocate memory for all of them at once.

Here is an example of a generator calculating Fibonacci numbers:

def fib(n) :
    a = b = 1
    for i in range(n):
        yield a
        a, b = b, a + b
Copy the code

Now we can use it like this:

for x in fib(1000000) :print(x)
Copy the code

So we don’t have to worry about it using a lot of resources. But if we implement it like this:

def fib(n) :
    a = b = 1
    result = []
    for i in range(n):
        result.append(a)
        a, b = b, a + b
    return result
Copy the code

It consumes all of our resources when it comes to calculating a large number of inputs. We’ve discussed that we can only iterate generators once, but we haven’t tested them yet. Before testing, you need to know about next(), another Python built-in function. It allows us to access the next element in the sequence. So let’s test our understanding:

def generator_function() :
    for i in range(3) :yield i

gen = generator_function()
print(next(gen))  # Each time next() is executed, it returns a result,
# Output: 0
print(next(gen))
# Output: 1
print(next(gen))
# Output: 2
print(next(gen))
# Output: Traceback (most recent call last):
# File "
      
       ", line 1, in 
       
# StopIteration
Copy the code

As we can see, next() results in a StopIteration error after all values have been generated. Basically this error tells us that all the values have been generated. You may be wondering why we don’t get this error when using a for loop? The answer is simple. The for loop automatically catches this error and stops calling Next. Did you know that some of Python’s built-in data types also support iteration? Let’s take a look:

string = "Yasoob"
next(string)
# Output: Traceback (most recent call last):
# File "
      
       ", line 1, in 
       
# TypeError: str object is not an iterator
Copy the code

Well, that’s not what we expected. Error: STR is not an iterator. Well, that’s right! It is an iterable but not an iterator. This means that it supports iteration, but we can’t iterate over it directly. So how are we going to iterate it? It’s time to get to know iter, another built-in function. Iterator returns an object from an iterable. We can use it on strings!

var = 1779
iter(var)
# Output: Traceback (most recent call last):
# File "
      
       ", line 1, in 
       
# TypeError: 'int' object is not iterable
# This is because int is not iterable

my_string = "YDAZHUANG"
my_iter = iter(my_string)  # convert to iter(iterable)
print(next(my_iter))
# Output: 'Y'
Copy the code