day14 learning function Advanced finishing -Python

20,190,813 finishing learning

Advanced Functions

A triplet of expressions

Return Values ​​When the condition else if condition is not satisfied when the conditions are satisfied

x = 10
y = 20
print(f"x if x > y else y:{ x if x > y else y}")
x if x > y else y: 20

List comprehensions

[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
类似于
res=[]
for item1 in iterable1:
    if condition1:
        for item2 in iterable2:
            if condition2
                ...
                for itemN in iterableN:
                    if conditionN:
                        res.append(expression)
print(F"[i for i in range(10)]: {[i for i in range(10)]}")
[i for i in range(10)]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(F"[i**2 for i in range(10)]: {[i**2 for i in range(10)]}")
[i**2 for i in range(10)]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
name_list = ['nick', 'sean', 'jason', 'tank']

print(
    f"[name if name=='nick' else name+'sb' for name in name_list]: {[name if name=='nick' else name+'sb' for name in name_list]}")
[name if name=='nick' else name+'sb' for name in name_list]: ['nick', 'seansb', 'jasonsb', 'tanksb']

Dictionary Builder

print({i: i**2 for i in range(10)})
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Builder

yield

yield of the English word meaning production, whenever the yield keyword appears in the function, and then call the function, the function body will not continue to execute the code, but will return a value.

def func():
    print(1)
    yield
    print(2)
    yield


g = func()
print(g)
<generator object func at 0x10ddb6b48>

Generator is essentially an iterator, but also not just an iterator, but uses other than the iterator is really small, so we can proudly say: generator provides a very convenient way of self-defined iterator. And starting from the Python 2.5+, [PEP 342: Generator achieve synergies through enhanced program] achieved by adding more features to the generator, which means that the generator can also get more work done. In this section we will introduce later in the section.

def func():
    print('from func 1')
    yield 'a'
    print('from func 2')
    yield 'b'


g = func()
print(F"g.__iter__ == g: {g.__iter__() == g}")

res1 = g.__next__()
print(f"res1: {res1}")

res2 = next(g)
print(f"res2: {res2}")

# next(g)  # StopIteration
g.__iter__ == g: True
from func 1
res1: a
from func 2
res2: b
def func():
    print('from func 1')
    yield 'a'
    print('from func 2')
    yield 'b'


g = func()
for i in g:
    print(i)

print(f"list(func()): {list(func())}")
from func 1
a
from func 2
b
from func 1
from func 2
list(func()): ['a', 'b']

yield+return??

Since the generator function is also a function, it can use the return output return value it?

Pro, since you have chosen a custom function as a generator, also return you doing? If this is the Python2, Python interpreter will be presented to you an exception, but in Python3, he also whether you such a fool behavior.

def i_wanna_return():
    yield 'a'
    yield 'b'
    return None
    yield 'c'


for i in i_wanna_return():
    print(i)
a
b

Iterator iterator sets (understand)

If I need to access another generator in the generator's iterative process an iterative how to do? Written below so silly, very naive. And what your intention is to do this? ? ?

def sub_generator():
    yield 1
    yield 2
    for i in range(3):
        yield i


for i in sub_generator():
    print(i)
1
2
0
1
2
def sub_generator():
    yield 1
    yield 2
    yield from range(3)


for i in sub_generator():
    print(i)
1
2
0
1
2

Coroutines (understand)

Coroutine (coroutine) generally refers to a function:

  • There are different from each other local variables, the instruction pointer, but still shared global variables;
  • You can easily suspend, resume, and a plurality of entry and exit points;
  • Synergy between multiple programs running performance of collaboration, such as the result of a process run A to B in the need to continue to perform.

Coroutine determine the characteristics of a moment, only a coordinated program is running (ignoring the case of multi-threaded). Thanks to this, coroutines can be passed directly between objects without regard to resource lock, or other direct wake-up process without the need for active co-sleep, like a built-in lock thread. In scenarios in line with the characteristics of coroutines, using the coroutine will undoubtedly be more convenient than using threads.

On the other hand, concurrent coroutines not in fact limit its application to the scene in a very narrow range, this feature makes the coroutine to be brought more compared with the conventional function, rather than thread. Of course, more complicated than many threads coroutine, and more powerful, so I suggest that you can firmly grasp the thread is not listening look ignorant force, then do not control him, because concurrent programming you'll relearn him. Therefore this section I will not enumerate examples of coroutines, and to understand the method described below.

Since Python2.5 + enhancement generator implements other features coroutine, in this version, a method of addition of the generator:

send(value):

The method of addition is next send another recovery generator. Python2.5 + in, yield statements into a yield expression, which means you can now have a yield value, and this value is to be called upon to restore execution method parameters send send method call generator.

def h():
    print('--start--')
    first = yield 5  # 等待接收 Fighting! 值
    print('1', first)
    second = yield 12  # 等待接收 hahaha! 值
    print('2', second)
    yield 13
    print('--end--')


g = h()
first = next(g)  # m 获取了yield 5 的参数值 5
# (yield 5)表达式被赋予了'Fighting!',  d 获取了yield 12 的参数值12
second = g.send('Fighting!')
third = g.send('hahaha!')  # (yield 12)表达式被赋予了'hahaha!'
print(f'--over--')
print(f"first:{first}, second:{second}, third:{third}")
--start--
1 Fighting!
2 hahaha!
--over--
first:5, second:12, third:13
  • Send incoming calls before non-None value, the generator must be in a suspended state, otherwise it will throw an exception. However, it does not start the generator can still use None as calling the send.
  • If you use the next recovery generator, the value of yield expression will be None.

close()

This method is used to close the generator. Call or send again to close next generation will raise StopIteration right.

def repeater():
    n = 0
    while True:
        n = (yield n)


r = repeater()
r.close()
print(next(r))  # StopIteration

throw(type, value=None, traceback=None)

Interrupt Generator is a very flexible technique can throw an exception through a GeneratorExit throw to terminate the Generator. Close () method does the same thing, in fact, inside it is called throw (GeneratorExit) of. We see the close of the source code:

def close(self):
    try:
        self.throw(GeneratorExit)
    except (GeneratorExit, StopIteration):
        pass 
    else:
        raise RuntimeError("generator ignored GeneratorExit") # Other exceptions are not caught

Custom range () method (to understand)

def my_range(start, stop, step=1):
    while start < stop:
        yield start
        start += 1


g = my_range(0, 3)
print(f"list(g): {list(g)}")
list(g): [0, 1, 2]

Summary (master)

yield:

  1. To provide a custom iterator way
  2. yield can live pause function, and provide a current return value

yield和return:

  1. The same point: both are functions used internally, can return values, and return value does not limit the type and number of
  2. Different points: return can only return once it; yield may return multiple values

Generator expressions (master)

  • The list of derived formula [] with () is the generator expression
  • Advantages: Provincial memory, once produced only one value in memory
t = (i for i in range(10))
print(t)
print(f"next(t): {next(t)}")
<generator object <genexpr> at 0x1101c4888>
next(t): 0

Generating a list of expressions and derivation of formula

List comprehensions give you the equivalent of a basket of eggs directly, and generate equivalent expressions give you an old hen.

# 生成器表达式
with open('52.txt', 'r', encoding='utf8') as f:
    nums = [len(line) for line in f]

print(max(nums))
1
# 列表推导式
with open('52.txt','r',encoding='utf8') as f:
    nums = (len(line) for line in f)

print(max(nums)) # ValueError: I/O operation on closed file.

Guess you like

Origin www.cnblogs.com/Wunsch/p/11348155.html