Export: comparison between iterative values and index values
Iterative values provide a new way that does not depend on index values.
- It does not depend on the index value and can be accessed by calling__ next__ () method value.
- Values cannot be repeated. You can only take values one by one from left to right. To get the same value, you can only reinitialize the iterator object and call__ next__ () method.
- The value object must be a container type, such as list, tuple, etc
- You can take values repeatedly, that is, a value can be taken multiple times at any time.
Generator and yield keyword
A generator is a custom iterator, essentially an iterator. If the function body contains the yield keyword, the function will not execute the function body code when called, and the returned result is a generator object. Built in generator__ iter__ () methods and__ next__ () method, called through the generator object__ next__ () method, which will trigger the execution of the function body code.
The yield keyword can be used to return a value, but unlike the return keyword, the function ends directly when it encounters a return, while the yield keyword can keep the function running and "pause" the function to return multiple values.
def index(): print('from index') yield index() print(index()) index().__next__() print(index().__next__())
Conclusion: the function body contains the yield keyword, the code is not executed when calling, and the returned result is the generator object; Generator object call__ next__ () method, execute the function body and return the value after yield. If it is not written, it returns None by default.
def index(): print('from index') yield 123,234,345 res = index() print(res.__next__()) # print(next(res)) # Consistent with the code in the previous sentence
Summary: you can return values after yield, and you can return multiple values at the same time, in the form of tuples.
def index(): print('for the first time next') yield 123,234,345 print('The second time next') yield 'aaaa' print('third time next') yield 'xxxx' res=index() # Once it's a generator, you can__ next__ Value print(res.__next__()) print(res.__next__()) print(res.__next__()) print(next(res)) # StopIteration
Summary: the generator object is called once__ next__ () method, walk a yield, and the cursor will stop at the yield. If you call again__ next__ (), it will continue to go down from the yield position of the last stop. If there is, it will execute. If not, it will throw an exception.
Note: after the yield keyword is in the function, it is still a function before the function call. Once the call function becomes a generator
Generator application example: the generator implements the range function
1. Function 1: range(10) # Numbers 0-9 2. Function 2: range(3,10) # Figures 3-9 3. Function 3: range(1, 10, 2) # 1,3,5,7,9
Use the generator to realize the range function:
def my_range(start, end=None, step=1): if not end: end = start start = 0 while start < end: yield start start += step # res = my_range(2, 10, 2) res = my_range(10) for i in res: print(i)
With the yield keyword, you can get the function's generator object to continue to be the send value of the function body.
def index(name): print('%s Get ready for dinner' % name) while True: food = yield print('%s Open dry %s' % (name, food)) res=index('handsome young man') res.__next__() res.__next__() res.send('Grilled rice') res.send('Rice')
Comparison between yield and return
- When the yield keyword is encountered in the function, the function is turned into a generator when called
- yield can also return a value, and supports multiple (tuple form) returns
- When yield is encountered, the function will not end, but "pause"
- yield also supports value passing (using the send method)
- Return can be followed by a return value, or multiple returns (in tuple form) are supported
- If the function encounters return, it will end immediately
We derive the generation expression from the list generation expression, as shown in the following code:
List generating formula:
l = [1,2,3,4] new_l = [i + 1 for i in l] print(new_l)
Execution result: [2, 3, 4, 5]
Summary: the return value of the list generator is the list
l = [1,2,3,4] new_l = (i + 1 for i in l) print(new_l) print(next(new_l))
Summary: the generator expression returns a generator object. To get the value, it needs to be generated through next(). The generator expression is similar to a "factory". When there is a demand, the "factory" will process "products" for you.
Generator written test questions
Title: write the execution results of the following procedures.
def add(n, i): return n + i def test(): for i in range(4): yield i g = test() for n in [1, 10]: g = (add(n, i) for i in g) res = list(g) print(res)
Implementation results: [20, 21, 22, 23]
# Sum def add(n, i): return n + i # The call is preceded by a function call and followed by a generator def test(): for i in range(4): yield i g = test() # Initialize generator object for n in [1, 10]: g = (add(n, i) for i in g) ''' First cycle: g = (add(1, i) for i in g) Second cycle: g = (add(10, i) for i in (add(10, i) for i in g)) ''' res = list(g) print(res)
Common built-in function supplement
abs(): find the absolute value.
print(abs(123)) print(abs(-123)) # Execution result: 123
all(): returns True only if all the elements in the list are True; otherwise, returns False.
l1 = [1,2,3,4,5,6] l2 = [1,2,3,0] print(all(l1)) print(all(l2)) # Execution result: true or false
any(): returns True as long as one of the elements in the list is True.
l1 = [1,2,3,4,5,6] l2 = [1,2,3,0] l3 = [0, None,] print(any(l1)) print(any(l2)) print(any(l3)) # Execution result: true True False
sum(): sum. Note that the incoming object must be an iteratable object.
l = [1,2,3,4,5,6] print(sum(l)) # Implementation result: 21
divmod(): divide remainder. The first parameter is the divisor, the second parameter is the divisor, and the return result is (quotient, remainder).
print(divmod(100,10)) print(divmod(101,10)) print(divmod(99,10)) # Execution result: (10, 0) (10, 1) (9, 9)
Application: Design of pager.
eval(), exec(): execute the code in the string. Note that the code in the string cannot be indented, otherwise an error will be reported.
string1 = """ print("hello world") """ eval(string1) eval(string1) # Execution results: hello world hello world
isinstance(): judge whether a data is an instance.
s = "hello world" print(isinstance(s, int)) print(isinstance(s, str)) # Execution results: False True
chr(): pass in decimal number and return ASCII characters corresponding to decimal number.
print(chr(65)) # Execution results: A
ord(): pass in ASCII characters and return the corresponding decimal digits.
print(ord('A')) # Execution results: 65
pow(): parameter 1 is the base, parameter 2 is the power, and the result is returned.
print(pow(2,3)) print(pow(3,3)) # Execution results: 8 27
round(): rounded to an integer after the decimal point.
print(round(4.3)) print(round(4.5)) print(round(4.8)) # Execution results: 4 4 5
bytes(): convert to binary.
s = 'hello world' print(bytes(s, 'utf8')) # Execution results: b'hello world'