# python:函数的高级特性

1.1 map示例：(将List中的所有元素*10)

def fn_map(x):
print("fn_map->", x)
return 10 * x

L = [3, 4, 6, 8]

print(list(map(fn_map, L)))
print("\n")

fn_map-> 3
fn_map-> 4
fn_map-> 6
fn_map-> 8
[30, 40, 60, 80]

def fn_sqrt(x, y):
print("fn_sqrt->", x, ",", y)
return math.sqrt(x ** 2 + y ** 2)

def fn_map(x):
print("fn_map->", x)
return 10 * x

L = [3, 4, 6, 8]

result = reduce(fn_sqrt, map(fn_map, L))
print(result)

print("\n")
print(math.sqrt((3 * 10) ** 2 + (4 * 10) ** 2 + (6 * 10) ** 2 + (8 * 10) ** 2))

注：要先import math，上面的代码输出如下：

fn_map-> 3
fn_map-> 4
fn_sqrt-> 30 , 40
fn_map-> 6
fn_sqrt-> 50.0 , 60
fn_map-> 8
fn_sqrt-> 78.10249675906654 , 80
111.80339887498948

111.80339887498948

def normalize(name):
return name[:1].upper() + name[1:].lower()

print(list(map(normalize, L1)))

1.2 filter

filter跟java8里的stream的filter是类似的，可以实现对集合中的元素，按某种规则进行筛选。

result = filter(lambda x: x % 2 == 0, range(1, 11))
print(list(result))

# 上面的写法，等效于下面这个
def even(x):
return x % 2 == 0

print(list(filter(even, range(1, 11))))

[2, 4, 6, 8, 10]
[2, 4, 6, 8, 10]

def is_palindrome1(n):
if n < 10:
return True
s = str(n)
for i in range(0, int(len(s) / 2)):
if s[i] == s[-i - 1]:
return True
return False

def is_palindrome2(n):
s1 = str(n)
s2 = list(reversed(s1))
return list(s1) == s2

print(list(filter(is_palindrome1, range(1, 201))))
print(list(filter(is_palindrome2, range(1, 201))))

[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]

1.3 sorted

python内置的排序函数sorted，支持数字/字母/以及复杂对象排序，默认是从小到大排序，对于复杂对象的排序规则可以开发者自定义。参考下面的示例:

origin = [-1, 3, -5, 2, -4, 6]
# 从小到大排序
a = sorted(origin)
print(a)

# 按abs绝对值，从小大到排序
a = sorted(origin, key=abs)
print(a)

# 从大到小排序
a = sorted(origin, reverse=True)
print(a)

origin = ["Xy", "Aa", "Bb", "dd", "cC", "aA", "Zo"]

# 按字母ascii值从小到大排序
print(sorted(origin))

# 将字母转大写后的值排序(即：忽略大小写)
print(sorted(origin, key=str.upper))

# 将字母转大写后的值倒排序
print(sorted(origin, key=str.upper, reverse=True))

# 复杂对象排序
origin = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_name(t):
return t[0]

# 按人名排序
print(sorted(origin, key=by_name))

def by_score(t):
return t[1]

# 按得分倒排
print(sorted(origin, key=by_score, reverse=True))

[-5, -4, -1, 2, 3, 6]
[-1, 2, 3, -4, -5, 6]
[6, 3, 2, -1, -4, -5]
['Aa', 'Bb', 'Xy', 'Zo', 'aA', 'cC', 'dd']
['Aa', 'aA', 'Bb', 'cC', 'dd', 'Xy', 'Zo']
['Zo', 'Xy', 'dd', 'cC', 'Bb', 'Aa', 'aA']
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]

python的函数定义可以嵌套（即:函数内部再定义函数），利用这个特性很容易实现延迟计算:

import time

def export1(month):
print("export1 month:", month, " doing...")
time.sleep(5)
print("export1 done!")

def export2(month):
def do():
print("export2 month:", month, " doing...")
time.sleep(5)
print("export2 done!")

return do

export1(10)

print("----------------")

r2 = export2(10)
print(r2)
r2()

export1 month: 10  doing...
export1 done!
----------------
<function export2.<locals>.do at 0x107a24a60>
export2 month: 10  doing...
export2 done!

def my_sqrt1(n):
r = []

def do():
for i in range(1, n + 1):
r.append(i ** 2)
return r

return do

a = my_sqrt1(4)
print(type(a))
b = a()
print(type(b))
print(b)

<class 'function'>
<class 'list'>
[1, 4, 9, 16]　　

def my_sqrt2(n):
r = []
for i in range(1, n + 1):
def do():
r.append(i ** 2)
return r

return do

a = my_sqrt2(4)
print(type(a))
b = a()
print(type(b))
print(b)

<class 'function'>
<class 'list'>
[16]

def my_sqrt3(n):
def f(j):
def g():
return j ** 2

return g

r = []
for i in range(1, n + 1):
r.append(f(i))

return r

a = my_sqrt3(4)
print(type(a))

for x in a:
print(x())

<class 'list'>
1
4
9
16

def create_counter1():
r = [0]

def counter():
r[0] += 1
return r[0]

return counter

count = create_counter1();

print([count(), count(), count()])

[1, 2, 3]

def create_counter2():
n = 0

def counter():
nonlocal n
n += 1
return n

return counter

count = create_counter2();

print([count(), count(), count()])

[1, 2, 3]

aop是java生态体系中的精髓之一，而python里同样能做到，而且看上去更简洁。

def add1(i, j):
return i + j　　

import time

def log(fn):
def do(*args, **kw):
start = time.time()
result = fn(*args, **kw)
end = time.time()
print("function=>", fn.__name__, ",args1=>", args, ",args2=>", kw, ",result=>", result, ",exec_time=>",
(end - start) * 1000, "ms")
return result

return do　　

@log
return i + j

print(add1(1, 2))

function=> add1 ,args1=> (1, 2) ,args2=> {} ,result=> 3 ,exec_time=> 0.0030994415283203125 ms
3

import time

def log(fn):
def do(*args, **kw):
start = time.time()
result = fn(*args, **kw)
end = time.time()
print("function=>", fn.__name__, ",args1=>", args, ",args2=>", kw, ",result=>", result, ",exec_time=>",
(end - start) * 1000, "ms")
return result

return do

def log2(log_prefix):
def around(fn):
def do(*args, **kw):
start = time.time()
result = fn(*args, **kw)
end = time.time()
print(log_prefix, ",function=>", fn.__name__, ",args1=>", args,
",args2=>", kw, ",result=>", result, ",exec_time=>",
(end - start) * 1000, "ms")
return result

return do

return around

@log2("调用日志:")
@log
time.sleep(1)
return i + j

print(add2(1, 2))

function=> add2 ,args1=> (1, 2) ,args2=> {} ,result=> 3 ,exec_time=> 1000.8599758148193 ms

3

import functools

return i + j

# 偏函数

print(add_10(1))

3
11

1、廖雪峰的python教程：函数式编程

984 篇文章76 人订阅

0 条评论

## 相关文章

### Go语言中new和make的区别

Go语言中new和make是内建的两个函数，主要用来创建分配类型内存。在我们定义生成变量的时候，可能会觉得有点迷惑，其实他们的规则很简单，下面我们就通过一些示例...

1927

382

### python3--列表推导式，生成器表达式，内置函数

3，python不但使用迭代器协议，让for循环变得更加通用，大部分内置函数，也是使用迭代器协议访问对象的，例如sum函数是python的内置函数，该函数使用迭...

4160

1051

2255

1321

1040

1041

5515

2653