This is 13 days of my participation in the November Gwen Challenge. See details of the event: The last Gwen Challenge 2021.

Generator (generator)

All the data in the list is in memory, which can be very memory consuming if there is a large amount of data.

For example, we only need to access the first few elements, but most of the memory that follows will be wasted. The generator, then, saves a lot of space by calculating successive elements as it loops through, rather than creating the entire list. In summary, when we want to use a lot of data, but we want it to take up less space, we use generators.

How to Create a generator

Generator expression

Generator expressions are derived from a combination of iteration and list parsing. Generators are similar to list parsing, but use () instead of [] :

g = (x for x in range(5)) print(g) # generator object print(next(g)) print(next(g)) print(next(g)) print(next(g)) Print (next(g)) for I in g: print(I)Copy the code

The generator

When a function contains the yield keyword, the function is no longer a normal function, but a generator. Generator expressions are derived from a combination of iteration and list parsing. Generators are similar to list parsing, but use () instead of []. Calling the function creates a generator object. It works by repeatedly calling the next() or __next__() methods until an exception is caught:

def yieldtest(number):
    n = 0
    # li = []
    while n<number:
        # li.append(n)
        yield n
        n+=1

res = yieldtest(20)
print(res)       # generator object
print(next(res)) # 0
print(next(res)) # 1
print(next(res)) # 2
Copy the code

⚠ ️ note:

  • yieldReturn a value, and remember the location of the return value, next timenext()When called, the code fromyieldThe next statement begins execution. withreturnThe difference between,returnAlso returns a value, but terminates the function directly.

For example, implement the Fibonacci sequence. Any number except the first and second can be obtained by adding the first two: 1,1,2,3,5,8,12,21,34…..

Def createNums(): print("-----func start-----") a,b = 0,1 for I in range(5): # print(b) print("--1--") yield b print("--2--") a,b = b,a+b print("--3--") print("-----func end-----") g = createNums()  print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g))Copy the code

send()

Send (), like next(), can make the generator go one step further (yield returns), but send() can pass a value that is the result of the yield expression as a whole:

def test():
    a1 = yield "hello"
    print("---1---")
    yield a1

res = test()
print(next(res))          # "hello"
print(res.send("world"))  # "world"
Copy the code

That is, the send method can force changes to the value of the last yield expression.

For example, if a function has a yield assignment:

a1 = yield "hello"
Copy the code
  1. The first iteration will return at this point"hello", buta1It hasn’t been assigned yet;
  2. For the second iteration, use.send("world");
  3. So, it is equivalent to forcible modificationyield "hello"The value of the expression is"world";
  4. soyield a1The results for"world".