1. filter(function, sequence):
对sequence中的元素执行function函数,返回由function函数执行结果为True的元素组成的序列,注意新序列类型与传入序列相同
测试:返回正数
#!/usr/bin/env python def findPositiveNum(num): if num > 0: return True else: return False nums = (3,2,1,0,-1,-2,-3) result = filter(findPositiveNum, nums) print result
结果:
(3, 2, 1)
2. map(function, sequence):
对sequence中的元素执行function函数,返回由function函数执行结果为元素组成的序列,如果function支持多个参数,map同样可以传递多个sequence,注意新序列类型为List, 作用是将一个列表映射到另一个列表
测试:对序列元素+1
#!/usr/bin/env python
def numPlusOne(num):
return num + 1
nums = (3,2,1,0,-1,-2,-3)
result = map(numPlusOne, nums)
print result
结果:
[4, 3, 2, 1, 0, -1, -2]
3. reduce(function, sequence, starting_value):
对sequence中的元素迭代执行function函数,同时支持starting_value作为初始值
python中的reduce内建函数是一个二元操作函数,他用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给reduce中的函数 func()(必须是一个二元操作函数)先对集合中的第1,2个数据进行操作,得到的结果再与第三个数据用func()函数运算,最后得到一个结果。
测试:以100为初始值计算序列和
#!/usr/bin/env python def addNum(num1, num2): return num1 + num2 nums = (4,3,2,1,0,-1,-2,-3) result = reduce(addNum, nums, 100) print result
结果:
104
def myadd(x,y):
return x+y
sum=reduce(myadd,(1,2,3,4,5,6,7))
print sum
#结果就是输出1+2+3+4+5+6+7的结果即28
当然,也可以用lambda的方法,更为简单:
Python代码
sum=reduce(lambda x,y:x+y,(1,2,3,4,5,6,7))
print sum
4. lambda:
使用lambda表达式可以定义一个匿名函数
测试:对传入值做加法
#!/usr/bin/env python addNum = lambda x : x + 2 result = addNum(1) print result print (lambda x: x + 2)(1)
结果:
3 3
5. zip:
函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表。具体意思不好用文字来表述,直接看示例:
x= [1,2,3]
y= [4,5,6]
zipped = zip(x,y)
print zipped
x2,y2 = zip(*zipped)
x == list(x2) and y== list(y2)
print x2
6、sorted()函数
Python内置的 sorted()函数可对list进行排序:
>>>sorted([36, 5, 12, 9, 21])
结果:[5, 9, 12, 21, 36]
但 sorted()也是一个高阶函数,它可以接收一个比较函数来实现自定义排序,比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。
因此,如果我们要实现倒序排序,只需要编写一个reversed_cmp函数:
def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
这样,调用 sorted() 并传入 reversed_cmp 就可以实现倒序排序:
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)
[36, 21, 12, 9, 5]
sorted()也可以对字符串进行排序,字符串默认按照ASCII大小来比较:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
‘Zoo’排在’about’之前是因为’Z’的ASCII码比’a’小。
列表推导式
基本形式:[x for item in sequence <if (conditions)>], 这里x表示对item的操作,
使用方法:
[i**2 for i in l]
Out[12]: [1, 4, 9, 16, 25, 36, 49, 64, 81]
字典设置默认值
Python字典中设置条目默认值在有些时候非常有用,例如初始化一个字典的时候。
使用方法:
x = {}
x.setdefault(1,0)
Out[15]: 0
x[2] = 10
x
Out[17]: {1: 0, 2: 10}
x.setdefault(2,1)
Out[18]: 10
列表推导式,也叫列表解析式,英文名称为list comprehension,可以使用非常简洁的方式来快速生成满足特定需求的列表,代码具有非常强的可读性。另外,Python的内部实现对列表推导式做了大量优化,可以保证很快的运行速度。列表推导式的语法形式为:
[表达式 for 变量 in 序列或迭代对象 if 条件表达式]
列表推导式在逻辑上相当于一个循环,只是形式更加简洁,例如:
>>> aList = [x*x for x in range(10)]
相当于
>>> aList = []
>>> for x in range(10):
aList.append(x*x)
当然也等价于
>>> aList = list(map(lambda x: x*x, range(10)))
而
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> aList = [w.strip() for w in freshfruit]
则等价于下面的代码
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> aList = []
>>> for item in freshfruit:
aList.append(item.strip())
也等价于
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> aList = list(map(lambda x: x.strip(), freshfruit))
或
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> aList = list(map(str.strip, freshfruit))
大家应该看过一个故事,说是阿凡提(也有的说是阿基米德,这不是重点)与国王比赛下棋,国王说要是自己输了的话阿凡提想要什么他都可以拿得出来。阿凡提说那就要点米吧,棋盘一共64个小格子,在第一个格子里放1粒米,第二个格子里放2粒米,第三个格子里放4粒米,第四个格子里放8粒米,以此类推,后面每个格子里的米都是前一个格子里的2倍,一直把64个格子都放满。结果可想而知,最后国王没有办法拿出那么多米。那么到底需要多少粒米呢,其实使用列表推导式再结合内置函数sum()就很容易知道答案。
>>> sum([2**i for i in range(64)])
18446744073709551615
接下来再通过几个示例来进一步展示列表推导式的强大功能。
(1)使用列表推导式实现嵌套列表的平铺
>>> vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
在这个列表推导式中有2个循环,其中第一个循环可以看做是外循环,执行的慢;而第二个循环可以看做是内循环,执行的快。上面代码的执行过程等价于下面的写法:
>>> vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> result = []
>>> for elem in vec:
for num in elem:
result.append(num)
>>> result
[1, 2, 3, 4, 5, 6, 7, 8, 9]
(2)过滤不符合条件的元素
在列表推导式中可以使用if子句来进行筛选,只在结果列表中保留符合条件的元素。例如下面的代码可以列出当前文件夹下所有Python源文件:
>>> import os
>>> [filename for filename in os.listdir('.') if filename.endswith('.py')]
下面的代码用于从列表中选择符合条件的元素组成新的列表:
>>> aList = [-1, -4, 6, 7.5, -2.3, 9, -11]
>>> [i for i in aList if i>0]
[6, 7.5, 9]
下面的代码使用列表推导式查找列表中最大元素的位置:
>>> from random import randint
>>> x = [randint(1, 10) for i in range(20)]
>>> m = max(x)
>>> m
10
>>> [index for index, value in enumerate(x) if value == m]
[0, 5, 6, 10]
>>> x
[10, 2, 3, 4, 5, 10, 10, 9, 2, 4, 10, 8, 2, 2, 9, 7, 6, 2, 5, 6]
(3)在列表推导式中使用多个循环,实现多序列元素的任意组合,并且可以结合条件语句过滤特定元素
>>> [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
注意:对于包含多个循环的列表推导式,一定要清楚多个循环的执行顺序或“嵌套关系”。例如,上面的代码等价于
>>> result = []
>>> for x in [1, 2, 3]:
for y in [3, 1, 4]:
if x != y:
result.append((x,y))
>>> result
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
(4)使用列表推导式实现矩阵转置
>>> matrix = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
或者,也可以使用内置函数zip()和list()来实现矩阵转置:
>>> list(map(list,zip(*matrix)))
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
注意:对于嵌套了列表推导式的列表推导式,一定要清楚其执行顺序。例如,上面列表推导式的执行过程等价于下面的代码,可以看出,使用列表推导式更加简洁,代码可读性更强。
>>> matrix = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> result = []
>>> for i in range(len(matrix)):
temp = []
for row in matrix:
temp.append(row[i])
result.append(temp)
>>> result
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
(5)列表推导式中可以使用函数或复杂表达式
>>> def f(v):
if v%2 == 0:
v = v**2
else:
v = v+1
return v
>>> print([f(v) for v in [2, 3, 4, -1] if v>0])
[4, 4, 16]
>>> print([v**2 if v%2 == 0 else v+1 for v in [2, 3, 4, -1] if v>0])
[4, 4, 16]
(6)列表推导式支持文件对象迭代
>>> fp = open('C:install.log', 'r')
>>> print([line for line in fp])
>>> fp.close()
(7)使用列表推导式生成100以内的所有素数
>>> [ p for p in range(2, 100) if 0 not in [ p% d for d in range(2, int(p**0.5)+1)] ]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
本文节选自(内容略有改动)《Python程序设计》(第2版),董付国编著,清华大学出版社,2016年6月出版,2016年11月第二次印刷。