current position:Home>Do you know the fuzzy semantics in Python syntax?

Do you know the fuzzy semantics in Python syntax?

2022-01-30 00:09:25 Python learner

1. The slice does not perform cross-border inspection and error reporting

What will be the output of the following code ?

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]
 Copy code 

The following code will output an empty list [] , Will not produce IndexError error . As expected , Try using more than the number of members index To get members of a list .

for example , Try to get list[10] And later members , It can lead to IndexError .

However , Try to get the slice of the list , At the beginning index Exceeding the number of members will not produce IndexError, It just returns an empty list .

This has become a particularly disgusting problem , Because there are no errors when running , Lead to bug It's hard to track .

2. Creation of empty list

1ist = [[ ]] * 5
list  # output?
list  # output?
list  # output?
list.append (30)
list  # output?
 Copy code 

2,4,6,8 What results will be output on the line ? Try to explain .

The output is as follows

 Copy code 

The output of the first line is intuitively easy to understand , for example list = [ [ ] ] * 5 Is simply created 5 An empty list . However , Understanding expressions list=[ [ ] ] * 5 The key point is that it doesn't create a list of five separate lists , Instead, it is a list created with five references to the same list . Only to understand this point , We can better understand the next output . 3. The key is coming. : Delay binding of closures

What will be the output of the following code ? Please explain .

#Python Learning exchange group :531509025

def multipliers():
    return [lambda x : i*x for i in range(4)]

print [m(2) for m in multipliers()]
 Copy code 

How do you modify the above multipliers The definition of produces the desired results ? The output of the above code is [6, 6, 6, 6] , Not what we think [0, 2, 4, 6] .

The reason for the above problems is Python Delay binding of closures . This means that when an internal function is called , The value of the parameter is searched in the closure . therefore , When any multipliers() When the returned function is called ,i The value of will be found in the nearby range . At that time , Whether the returned function is called or not ,for The cycle is complete ,i Given the final value 3.

therefore , Each time the function returned is multiplied by the value passed 3, Because the value of the previous code is 2, They all end up returning 6(3*2). It happened that ,《The Hitchhiker’s Guide to Python》 Also pointed out , With the lambdas There is also a widely misunderstood point of knowledge about functional correlation , But with this case Dissimilarity . from lambda There is nothing special about the functions created by expressions , It's actually with def The function created is the same .

Here are some ways to solve this problem .

One solution is to use Python generator .

def multipliers():
    for i in range(4): yield lambda x : i * x
 Copy code 

Another solution is to create a closure , Use the default function to bind immediately .

def multipliers():
    return [lambda x, i=i : i * x for i in range(4)]
 Copy code 

Another alternative is , Use partial functions :

from functools import partial
from operator import mul

def multipliers():
    return [partial(mul, i) for i in range(4)]
 Copy code 

copyright notice
author[Python learner],Please bring the original link to reprint, thank you.

Random recommended