1.列表生成式
通过range(1,11)
可以生成1到10的整数列表,如果要生成更复杂的列表,一是通过循环和append()
,另一种更简单的方式是通过列表生成式:
[x*x for x in range(1, 11)]
[1, 4, 9, ......]
for循环后面还可以添加if判断:
[x*x for x in range(1, 11) if x%2 == 0]
[4, 16, 36, 64, 100]
还可以使用两层循环,生成全排列
[m+n for m in 'ABC' for n in 'def']
['Ad', 'Ae', 'Af', 'Bd', 'Be', 'Bf', 'Cd', 'Ce', 'Cf']
2.生成器
可以一边循环一边计算,不用创建整个列表,节省空间
创建方法一是把列表生成式的[]
改为()
,
调用next()
得到元素,或者用for
循环,推算的算法比较复杂的话就用函数实现,只需要把函数中产生元素的语句写为yield b
def fib(max):
a, b, n = 0, 1, 0
while n < max:
yield b
a, b = b, a+b
n = n+1
遇到yield
返回,调用next()
接着上次的yield
继续执行, 函数体都执行完后结束
print fib(6)
<generator object fib at 0x02DC2E40>
for x in fib(6):
print x
1
1
2
...
3.map/reduce
map()
接受两个参数,第一个是函数,第二个是序列,输出结果是把函数作用在序列上之后的结果
map(str, [1, 2, 3])
['1', '2', '3']
reduce()
也接受同样的两种参数,它的方法是把结果继续和序列的下一个元素做累积计算:
def add(x,y)
return x+y
reduce (add, [1, 2, 3, 4])
(((1+2)+3)+4) = 10
4.补充知识点
①{dic}[key]
可以得到对应的value值
{'One': 1, 'Two': 2}['One']
1
②
str.upper() //把所有字符中的小写字母转换成大写字母
str.lower() //把所有字符中的大写字母转换成小写字母
str.capitalize() // 把第一个字母转化为大写字母,其余小写
str.title() // 把每个单词的第一个字母转化为大写,其余小写
5.filter
filter()
接受两个参数,一是函数,而是序列,函数作用在序列的每个元素上,如果是Tree
就输出,是False
就过滤掉
def not_empty(s):
return s and s.strip()
print filter(not_empty, ['A', '', 'B', None, 'C', ' '])
['A', 'B', 'C']
ps:strip(x)
表示去掉字符串收尾的x元素
6.sorted
内置的sorted()
可以直接排序,从小到大。
还可以接入其他的比较函数来进行排序,比如从大到小:
def recmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
sorted([15, 25, 65], recmp)
[65, 25, 15]
7.返回函数
把函数作为返回值
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
此时,调用lazy_sum()
时,返回的不是求和结果,而是求和函数
f = lazy_sum(1, 3, 5, 7, 9)
f
<function sum at 0x10452f668>
调用函数f
时,才真正计算求和结果
f()
25
8.匿名函数
匿名函数由关键字lambda
实现,lambda x: x*x
,冒号前面表示参数,后面是函数表达式,返回值即为该表达式的结果,只能有一个表达式。
9.装饰器
当我们需要增加某个函数的功能,又不想改变函数定义时,可以使用装饰器decorator。本质上,decorator是一个返回函数的高阶函数。
def time():
print '2018-1-8'
//函数对象有一个__name__属性,可以得到函数名字
假如要增强time()
的功能,在调用的时候能打日志。
def log(func)://接受一个函数
def wrapper(*args, **kw):
print 'call %s():' %func.__name__
return func(*args, **kw)
return wrapper
@log
def time():
print '2018-1-8'
time()
call time():
2018-1-8
把@log
放在time()
的定义出,相当于执行了time = log(time)
如果decorator本身要传入参数,比如要自定义log的文本
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print '%s %s():' %(text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
@log('Hello')
def time():
print '2018-1-8'
time()
result:
Hello time():
2018-1-8
三层嵌套的效果是time = log('Hello')(time)
但此时,time
的__name__
属性变成了'wrapper'
,有些依赖函数签名的代码执行就会出错。所以还要将原函数的__name__
属性复制过来
import functools//导入functools模块
//然后在定义wrapper()函数的上面加上@functools.wraps(func)
10.偏函数
偏函数(Partial function)是functools
模块的一个功能,它可以把一个函数的某些参数固定住,比如int()
函数有base
参数,传入base
参数可以做n进制的转换(原来是base进制,转为10进制输出)
int('12345', base=8)
5349
使用偏函数创建一个进行二进制转换的int()
函数:
import functools
int2 = functools.partial(int, base=2)
创建偏函数时,接受函数对象、*args
、**kw
这三个参数,以上代码相当于:
kw = { base: 2}
int2 = functools.partial(int, **kw)