Python 高级特性
本文的Python知识基于 Python3
函数的本质
我们的函数名, 本质上就是个变量
>>> print
<built-in function print>
>>> type(print)
<class 'builtin_function_or_method'>
>>> print = 10
>>> print
10
>>> type(print)
<class 'int'>
>>> 注意, 执行完成上述代码需要重新打开shell
>>> num = 10
>>> print(num)
10
>>> other = num
>>> print(other)
10
>>> other = print
>>> other("Hades Studio")
Hades Studio
>>> def foo(x, f):
... f(x)
...
>>> foo (10, print)
10
>>> map方法
- 对
可迭代对象中的每一个元素应用function方法, 并返回迭代器 如果给了多个可迭代参数
- 则给定的函数必须采用
多参数的写法, 或者函数的参数正好匹配也行
通俗的说, 如果你提供了2个可迭代的参数, 那么你的函数必须要能接受这两个参数
- 可以是 def foo (*args) 写法
- 比如有2个参数, 也可以 def foo (x, y)
每个可迭代对象的相同下标的值都会进行func的运算
- 也就是, 比如第一次执行func, 会将所有传递的可迭代对象的[0]元素拿出来参与计算
- 第二次, 会将[1]元素拿出来计算
- ....
- 则给定的函数必须采用
- 如果给出的可迭代参数长短不一致, 则使用最短的可迭代参数的长度进行计算
- map的返回值是
map对象, 官方文档说是 迭代器
>>> # map的简单应用
>>> iterObj = map(print, [1,2,3,4,5,6,7])
>>> type(iterObj)
<class 'map'>
>>> list(iterObj)
1
2
3
4
5
6
7
[None, None, None, None, None, None, None]
'''
... 这里, 传递的list的每一个元素都调用了print, 所以打印了 1--7
... 然后, print的返回值是None, 所以有7个None形成了一个list
'''
# ========================================================
>>> # 单一参数的函数, 返回1个值
>>> def foo(x):
... return x ** 2 # 求立方
...
>>> list(map(foo, list(range(10)))) # 计算 1--9 的立方
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# ========================================================
>>> # 多个参数的函数, 返回1个值
>>> def add(x, y) :
... return x + y
...
>>> lst1 = [1,2]
>>> lst2 = [5,6]
>>> list(map(add, lst1, lst2)) # 返回 1+5, 2+6
[6, 8]
>>> list(map(add, [3,4], [7,8])) # 返回 3+7, 4+8
[10, 12]
>>> list(map(add, [3,4], [7,8,9])) # 返回 3+7, 4+8
[10, 12]
>>> list(map(add, [3,4,5,6], [7,8,9])) # 返回 3+7, 4+8, 5+9
[10, 12, 14]
>>> list(map(add, [[3,4,5],[6,7,8]], [[1,2,3],[5,6,7]])) # 返回 [3,4,5] + [1,2,3], [6,7,8] + [5,6,7] 这是list的加
[[3, 4, 5, 1, 2, 3], [6, 7, 8, 5, 6, 7]]
>>>
# ========================================================
>>> # 多个参数的函数, 多个返回值
>>> def foo(x, y):
... return x * y, x + y
...
>>> lst1 = [1,2]
>>> lst2 = [5,6]
>>> list(map(foo, lst1, lst2)) # 返回 (1*5, 1+5), (2*6, 2+6), 返回的是 元组 组成的list
[(5, 6), (12, 8)]
>>> list(map(foo, [3,4], [7,8])) # 返回 (3*7, 3+7), (4*8, 4+8), 返回的是 元组 组成的list
[(21, 10), (32, 12)]
>>> list(map(foo, [3,4], [7,8,9])) # 返回 (3*7, 3+7), (4*8, 4+8), 返回的是 元组 组成的list
[(21, 10), (32, 12)]
>>> list(map(foo, [3,4,5,6], [7,8,9])) # 返回 (3*7, 3+7), (4*8, 4+8), (5*9, 5+9), 返回的是 元组 组成的list
[(21, 10), (32, 12), (45, 14)]
>>>
# ========================================================
>>> # 方法为多参数
>>> def foo(*args):
... xargs = 1;
... for arg in args:
... xargs *= arg
... return xargs
...
>>> lst1 = [1,2]
>>> lst2 = [5,6]
>>> list(map(foo, lst1, lst2))
[5, 12]
>>> list(map(foo, [3,4], [7,8]))
[21, 32]
>>> list(map(foo, [3,4], [7,8,9]))
[21, 32]
>>> list(map(foo, [3,4],[5,6], [7,8],[9, 10]))
[945, 1920]
>>> 常用map技法
>>> # 将元组转换成list
... list(map(int, (1,2,3)))
...
[1, 2, 3]
>>> # 将字符串转换成list
... list(map(int, '1234'))
...
[1, 2, 3, 4]
>>> # 提取字典的key,并将结果存放在一个list中
... list(map(int, {1:2,2:3,3:4}))
...
[1, 2, 3]
>>> # 字符串转换成元组,并将结果以列表的形式返回
... list(map(tuple, 'Hades'))
...
[('H',), ('a',), ('d',), ('e',), ('s',)]
>>> # 将小写转成大写
... def lower2upper(str):
... return str.upper()
...
>>> list(map(lower2upper,'Hades'))
['H', 'A', 'D', 'E', 'S']
>>> reduce
使用reduce必须要
import functools包- 可以使用
from functools inport reduce来最小导入
- 可以使用
将
两个参数的函数累计到序列项中,从左到右, 以便将序列减少到单个值- 官方翻译, 比较难理解
- 意思就是, 每次都拿着上一次计算的结果去计算, 直到没有元素可计算了
- 比如以下计算阶乘代码:
def factorial(x, y): return x * y reduce(factorial, list(range(1, 10))) # 1*2*3*4*5*6*7*8*9reduce函数可以设置初始值
- reduce(factorial, list(range(1, 10)), 1000)
>>> # 全部导入 不推荐
... # import functools
...
>>> # 单一导入 推荐
... from functools import reduce
...
>>> def factorial(x, y):
... return x * y
...
>>> reduce(factorial, list(range(1, 10))) # 1*2*3*4*5*6*7*8*9
362880
>>> reduce(factorial, list(range(1, 10)), 1000) # 1*2*3*4*5*6*7*8*9 * 1000
362880000
>>> map和reduce结合的一个应用
字符串转整数
>>> def list2num(x, y):
... return x * 10 + y
...
>>> def str2num(str):
... return {'0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}[str]
...
>>> num = reduce(list2num, map(str2num, '987654321234567890'))
>>> print(num)
987654321234567890
>>> filter
- 过滤器
- 返回一个迭代器
- 这个迭代器会返回指定
方法为True时的元素 - 如果函数为
None, 则默认什么元素都不返回
>>> def isodd(num):
... return num % 2 == 1
...
>>> num = reduce(list2num, filter(isodd, map(str2num, '1234567890987654321')))
>>> print(num)
1357997531
>>> num = reduce(list2num, sorted(filter(isodd, map(str2num, '1234567890987654321'))))
>>> print(num)
1133557799
>>> sorted
- 排序函数
- 默认
升序排列 - 可以通过
key指定函数
>>> sorted(['a', 'c', 'b', 'd', 'A'])
['A', 'a', 'b', 'c', 'd']
>>> mylist = ['a', 'z', 'c', 'A']
>>> sorted(mylist, key = str.lower)
['a', 'A', 'c', 'z']
>>> 延迟调用的函数
- 函数会先在这里, 等到我们需要的时候在去调用
- 我们的
生成器就是延迟调用的
>>> def sum(*args):
... n_sum = 0
... for num in args:
... n_sum += num
... return n_sum
...
>>> num = sum(1,2,3,4,5)
>>> print(num)
15
>>> def lazysum(*args):
...
... def sum():
... n_sum = 0
... for num in args:
... n_sum += num
... return n_sum
...
... return sum
...
>>> num = lazysum(1,2,3,4,5)
>>> print(num)
<function lazysum.<locals>.sum at 0x05738E40>
>>> print(num())
15
>>> print(num)
<function lazysum.<locals>.sum at 0x05738E40>
>>> print(num())
15
>>> lambda表达式
- 匿名函数
- 以
lambda开头, 后面跟变量 - 变量列表后是
:, 然后是函数体, 在一行上 - 无return语言
- 无需def, 无名字, 直接赋值给一个变量使用
它会使代码更简洁
- 程序运行效率的问题暂不研究....
- 如果可以使用for...in...if来完成的, 不推荐用lambda
如果使用lambda, 不要包含循环.
- 如果有, 建议定义函数
- 能使代码有可重用性和更好的可读性
# lambda表达式 匿名函数
>>> # 一个参数的匿名函数
... foo = lambda num: num * num
...
>>> print(foo(10))
100
>>> list(foo for foo in range(2, 8)) # 配合 列表生成器
[2, 3, 4, 5, 6, 7]
>>> list(x*x for x in range(2, 8)) # 与上边等效
[4, 9, 16, 25, 36, 49]
>>>
# lambda表达式的小应用
>>> lst = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>> list(filter(lambda x: x % 3 == 0, lst))
[18, 9, 24, 12, 27]
>>> # 等价于
... list(x for x in lst if x % 3 == 0)
...
[18, 9, 24, 12, 27]
>>> list(map(lambda x: x * 2 + 10, lst))
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>> # 等价于
... list(x * 2 + 10 for x in lst)
...
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>> reduce(lambda x, y: x + y, lst)
139
>>>
# 去掉首尾空格
>>> collapse = False
>>> processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
>>> processFunc("asdfadsfasdfadf")
'asdfadsfasdfadf'
>>> processFunc(" asdf a d as f a sd f adf ")
' asdf a d as f a sd f adf '
>>> collapse = True
>>> processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
>>> processFunc("asdfadsfasdfadf")
'asdfadsfasdfadf'
>>> processFunc(" asdf a d as f a sd f adf ")
'asdf a d as f a sd f adf'
>>> 函数绑定
- 使用
functools.partial来将函数绑定上参数 - 可以形成一个"新的"函数
>>> int('0xFF', base=16)
255
>>> int('FF', base=16)
255
>>> int('11', 2) # 2进制转10进制
3
>>> bin2dec = functools.partial(int, base=2)
>>> bin2dec('1010110010101')
5525
>>> bin2dec('11111111')
255
>>> hex2dec = functools.partial(int, base=16)
>>> hex2dec('FF')
255
>>> hex2dec('abcd')
43981
>>> 未完待续...
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-07-16 at 04:07 am