python-higher order function/map/reduce/filter()/Sorted

table of Contents

Higher order function

map/reduce

filter()

Sorted


Higher order function

Variables can point to functions, and the function itself can also be assigned to variables , that is: variables can point to functions

>>> f = abs
>>> f(-10)
10

The function name is also a variable , the function name is actually the variable that points to the function

A function can receive another function as a parameter, this function is called a higher-order function

#一个最简单的高阶函数:
def add(x, y, f):
    return f(x) + f(y)

The derivation process when calling the above function is as follows

x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11

map/reduce

map()The function receives two parameters, one is a function, and the other is Iterableto mapapply the passed function to each element of the sequence in turn, and return the result as a new one Iterator.

>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

map()The first parameter passed in fis the function object itself. Since the result ris one Iterator, it Iteratoris a lazy sequence, so list()let it calculate the entire sequence through a function and return a list

reduce(function, sequence, initializer=None) applies a function to a sequence[x1, x2, x3, ...], this function must receive two parameters, andreducethe result continues to be accumulated with the next element of the sequence.

  • If the optional parameter initializer is provided, it is equivalent to inserting it as an element of the sequence into the first part of the sequence

The effect is:

For example, to sum a sequence:

>>> from functools import reduce
>>> def add(x, y):
...     return x + y
>>> reduce(add, [1, 3, 5, 7, 9])
25

If we consider that a string stris also a sequence, with a slight modification to the above example map(), we can write a function to strconvert toint :

>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
>>> def char2num(s):
...     digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
...     return digits[s]
>>> reduce(fn, map(char2num, '13579'))
13579

str2intThe function organized into one is:

from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def str2int(s):
    def fn(x, y):
        return x * 10 + y
    def char2num(s):
        return DIGITS[s]
    return reduce(fn, map(char2num, s))

You can also use lambda functions to further simplify:

from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def char2num(s):
    return DIGITS[s]
def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))

filter(function, iterable)

Used to filter the sequence 

filter()It also receives a function and a sequence. The map()difference is that filter()the passed function acts on each element in turn, and then decides Truewhether Falseto keep or discard the element according to the return value . To delete the empty string in a sequence, you can write:

 

def not_empty(s):
    return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
# 结果: ['A', 'B', 'C']

Use filter to find prime numbers

One method of calculating prime numbers is the Ehrlich Sieve method , and its algorithm is very simple to understand:

First, list 2all natural numbers from the beginning to construct a sequence: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

Take the first number of the sequence 2, it must be a prime number, and then filter out the multiples of 2the sequence 2: 3,  4 , 5,  6, 7,  8 , 9,  10 , 11,  12 , 13,  14, 15,  16 , 17,  18 , 19,  20 , take the first number of the new sequence 3, it must be a prime number, and then filter out the multiples of 3the sequence 3: 5,  6 , 7, 8,  9 , 10, 11,  12 , 13 , 14,  15 , 16, 17,  18 , 19, 20, ... take the first number of the new sequence 5, and then filter out the multiples of 5the sequence 5: 7, 8, 9,  10 , 11, 12, 13 , 14,  15,  16, 17, 18, 19,  20 , ... Keep sifting down, and you can get all the prime numbers.

def _odd_iter(): #构造一个从3开始的奇数序列
    n = 1
    while True:
        n = n + 2
        yield n
def _not_divisible(n): #定义一个筛选函数
    return lambda x: x % n > 0

def primes():  #定义一个生成器,不断返回下一个素数
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it) # 构造新序列
# 打印1000以内的素数:
for n in primes():
    if n < 1000:
        print(n)
    else:
        break

Sorted

sorted()Function is also a higher-order function, it can also receive a keyfunction to achieve custom sorting, such as sorting by absolute value:

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

 To sort strings , in accordance with the size of the ASCII comparison

Suppose we use a set of tuples to represent student names and grades:

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

Use sorted()to sort the above list by name:

L = [('Bob',75), ('Admin', 92), ('Bart', 66), ('List', 88)]
def by_name(t):
    return t[0].lower()
L2 = sorted(L, key=by_name)
print(L2)

Sorting a list of tuples
Suppose we use a set of tuples to represent names and ages, and then use the sorted() function to sort the names in ascending order and age in descending order:

def sort_by_name(t):
    return t[0]

def sort_by_age(t):
    return t[1]

L = [('Tom', 18), ('Jerry', 15), ('Peter', 16), ('John', 20)]
list1 = sorted(L, key=sort_by_name)
list2 = sorted(L, key=sort_by_age, reverse=True)
print('sort by name asc: ', list1)
print('sort by age desc: ', list2)

Output result:

sort by name asc:  [('Jerry', 15), ('John', 20), ('Peter', 16), ('Tom', 18)]
sort by age desc:  [('John', 20), ('Tom', 18), ('Peter', 16), ('Jerry', 15)]

Example 4: Sorting the contents of a dictionary

There are many ways to sort a dictionary, but the core idea is the same: separate the key or value or item in the dict into a list, and then sort the list, thereby indirectly sorting the dict.

D = {'Tom': 18, 'Jerry': 15, 'Peter': 16, 'John': 20}

list1 = sorted(D.items(), key=lambda d: d[0])
list2 = sorted(D.items(), key=lambda d: d[1], reverse=True)

print('sort by key asc:', list1)
print('sort by value desc:', list2)

Output result:

sort by key asc: [('Jerry', 15), ('John', 20), ('Peter', 16), ('Tom', 18)]
sort by value desc: [('John', 20), ('Tom', 18), ('Peter', 16), ('Jerry', 15)]

 

Guess you like

Origin blog.csdn.net/zangba9624/article/details/106186117