Is there such a problem that you really understand python programming from now on?

Tianyuan prodigal son 2020-11-13 09:09:30
problem really understand python programming

When I write down this topic , In my mind, I couldn't help but hear Zhou Huajian's slightly hoarse voice ：

The familiar song came from afar ,
Why are those voices so weak .
long time no see , Are you all right now ？
Is there such a song ,
Will let you follow and ,
With the ups and downs of our lives ,
A theme song to sing together ;
Is there such a song ,
It will remind you of me ,
Make you happy and worry ,
Such a me ……

The music is over , Back to the point . Browse recently LeetCode, I found an interesting little topic . When I try Python When you answer , Actually used the assembly 、map function 、zip function 、lambda function 、sorted function , The debugging process also involves iterators 、 generator 、 The concept of list derivation . A seemingly simple topic , Although the final code can be combined into one line , But almost put Python I used the programming skills of , It can be said. “ The subtlety is the spirit ”！ Through this topic , Maybe it will make you really understand Python Programming .

This question , be known as 《 The lucky number in the list 》. What is the lucky number ？ In the list of integers , If a number appears at the same frequency as its value , We call this number 「 Lucky number 」. for example , In the list [1, 2, 2, 3] in , Numbers 1 And number 2 The number of times they appear is 1 and 2, So they are lucky numbers , but 3 Only ever 1 Time ,3 It's not a lucky number .

I understand the concept of lucky number , Let's try to find out the list [3, 5, 2, 7, 3, 1, 2 ,4, 8, 9, 3] The lucky number in . This process can be divided into the following steps ：

1. Find out the numbers that are not repeated in the list
2. Count the number of times each number appears in the list
3. Find out the numbers that appear equal to the number itself

The first 1 Step , Find out the numbers that are not repeated in the list

Find out the numbers that are not repeated in the list , That is, to remove duplicate elements from the list , abbreviation “ duplicate removal ”. The simplest way to de duplicate is to use sets .

``````>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]
>>> unique = set(arr)
>>> unique
{
1, 2, 3, 4, 5, 7, 8, 9}
``````

The first 2 Step , Count the number of times each number appears in the list

We know , The list object comes with a count() Method , Can return the number of times an element appears in the list , The usage is as follows ：

``````>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]
>>> arr.count(8) # Elements 8 In the array arr There has been 2 Time
2
``````

Next , We only need to traverse the elements after de duplication , Count the number of times they appear one by one , And save it into a suitable data structure , This step of the work will be all right .

``````>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]
>>> unique = set(arr) # Remove duplicate elements
>>> pairs = list() # An empty list , Used to hold tuples of array elements and occurrence times
>>> for i in unique:
pairs.append((i, arr.count(i)))
>>> pairs
[(1, 1), (2, 2), (3, 3), (4, 1), (5, 1), (7, 1), (8, 2), (9, 1)]
``````

As a rookie , Code like this , Has been very good . however , A aspiring programmer will never be complacent about it 、 come to a standstill . Their favorite thing to do is to do everything possible to eliminate for loop , For example, using mapping functions 、 Filter function instead of for loop ; Even if you can't refuse for loop , They also try to hide the cycle as much as possible , For example, hiding in list derivation . Since this is to call the list for every element count() This method , That's the best way to use map Function instead of for Circulated .

``````>>> m = map(arr.count, unique)
>>> m
<map object at 0x0000020A2D090E08>
>>> list(m) # Generators can be converted to lists
[1, 2, 3, 1, 1, 1, 2, 1]
>>> list(m) # The generator can only be used once , After use , It's automatically cleaned up
[]
``````

map The function returns a generator （generator）, It can be traversed like a list , But you can't see the elements as intuitively as a list , Unless we use list() Turn this generator into a list （ You don't actually need to turn the generator into a list ）. Please note that , Generators are different from iterators , Or a generator is a special kind of iterator , Can only be traversed once , End of traversal , It's gone . Iterators can iterate over and over . such as ,range() Function returns iterator ：

``````>>> a = range(5)
>>> list(a)
[0, 1, 2, 3, 4]
>>> list(a)
[0, 1, 2, 3, 4]
``````

Say generator and iterator , We have to go back to the original topic . Use map Mapping function , We get the number of occurrences of each element , You also need to form a tuple with the corresponding elements . Now , Just use zip() Function .zip() Function to create a generator , Used to aggregate every iteratable object （ iterator 、 generator 、 list 、 Tuples 、 aggregate 、 String, etc. ） The elements of , Elements aggregate according to the same subscript , If the length is different, elements larger than the shortest iteration object length will be ignored .

``````>>> m = map(arr.count, unique)
>>> z = zip(unique, m)
>>> z
<zip object at 0x0000020A2D490508>
>>> list(z)
[(1, 1), (2, 2), (3, 3), (4, 1), (5, 1), (7, 1), (8, 2), (9, 1)]
>>> list(z)
[]
``````

Obviously ,zip() The function also returns the generator , It can only be used once , Then it disappears .

The first 3 Step , Find out the numbers that appear equal to the number itself

With each element and its number of occurrences , We just need to loop through …… No , One moment please , Why do we have to cycle ？ We just need to filter every element , Find out the tuples that have the same number of occurrences as the element itself , Why not try the filter function filter() Well ？

``````>>> def func(x): # Parameters x It's a tuple type
if x[0] == x[1]:
return x
>>> m = map(arr.count, unique)
>>> z = zip(unique, m)
>>> f = filter(func, z)
>>> f
<filter object at 0x0000020A2D1DD908>
>>> list(f)
[(1, 1), (2, 2), (3, 3)]
>>> list(f)
[]
``````

Filter function filter() Take two parameters , The first 1 A parameter is a function , Used to determine whether an element meets the filtering conditions , The first 2 One parameter is the iteratable object to be filtered .filter() The function also returns the generator , It can only be used once , Then it disappears .

Write here , We're almost done . however , As a pursuing programmer , You can tolerate func() Such a strange looking function ？ The answer is no ！ You must be able to use lambda Function to replace it . in addition , Maybe we need to sort the results by the size of the elements . Add sorting , The complete code is as follows ：

``````>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]
>>> unique = set(arr)
>>> m = map(arr.count, unique)
>>> z = zip(unique, m)
>>> f = filter(lambda x:x[0]==x[1], z)
>>> s = sorted(f, key=lambda x:x[0])
>>> print(' The lucky number is ：', [item[0] for item in s])
The lucky number is ： [1, 2, 3]
``````

The ultimate code , One line fix

If you've ever been written in one line by those 、 But it can achieve complex functions 、 The painful experience of code ravaging that looks like a heavenly book , that , Now you can also write the above code in one line , To ravage others .

``````>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]
>>> print(' The lucky number is ：', [item[0] for item in sorted(filter(lambda x:x[0]==x[1], zip(set(arr), map(arr.count, set(arr)))), key=lambda x:x[0])])
The lucky number is ： [1, 2, 3]
``````

Dramatic reversal , I really understand this time Python 了 ！

This blog has not been published for two days , Some netizens left a message saying , Why bother ？ It's not easier to write like this 、 Is it easier to read ？ Sure enough , I really want to ！

``````>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]
>>> [x for x in set(arr) if x == arr.count(x)]
[1, 2, 3]
``````