Python学习笔记(三)
三个内置函数 map filter reduce 和列表推导(List Comprehensions)##
map(func,list):将list的每一个元素传递给func的函数,这个函数有一个参数,且返回一个值,map将每一次调用函数返回的值组成一个新列表返回。
filter(func,list):将list的每一个元素传递给func的函数,这个函数有一个参数,返回bool类型的值,filter将返回True的元素组成新列表返回。
reduce(func,list):将list的元素,挨个取出来和下一个元素通过func计算后将结果和再下一个元素继续计算
filter(function, sequence) 过滤 function(item) 为true:
>>> def f(x): return x % 3 == 0 or x % 5 == 0
...
>>> filter(f, range(2, 25))
[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]
>>> def f(x): return x in 'aeiou'
>>> filter(f,('a','c','b','e'))
('a', 'e')
map(function,sequence)
对于sequence 里面的每个item调用 function(item)
返回值形成一个新的
list 示例代码:
>>> def cube(x): return x**3
...
>>> map(cube,range(1,11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
如果操作的sequence多于一个,也可以调用function(item1,item2),示例代码:
>>> seq = range(8)
>>> def add(x,y): return x+y
...
>>> map(add,seq,seq)
[0,2,4,6,8,10,12,14]
reduce(function,sequence[,initial])
返回一个值,对序列中的元素进行逐个计算,例如计算1-10的和:
>>> def add(x,y): return x+y
...
>>> reduce(add,range(1,11))
55
注意如果sequence为空,那会抛出异常,需要设置initial 示例代码:
>>> def sum(seq):
... def add(x,y): return x+y
... return reduce(add, seq, 0)
...
>>> sum(range(1, 11))
55
>>> sum([])
0
列表推导###
将符合列表公式的代码写在列表定义中,可以简化代码。
例如:
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
等价于:
squares = [x**2 for x in range(10)]
也可以等价于map和filter函数:
>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print(filter(lambda x: x % 3 == 0, foo))
等价于
print([x for x in foo if x % 3 == 0])
print(map(lambda x: x * 2 + 10, foo))
等价于
print([x * 2 + 10 for x in foo])
循环过滤素数算法:
# 求2到49范围内的素数
>>> nums = range(2, 50)
>>> for i in range(2, 8):
nums = [x for x in nums if x==i or x % i != 0]
>>> nums
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
另一种实现:
#单行程序扫描素数
from math import sqrt
N = 100
[ p for p in range(2, N) if 0 not in [ p% d for d in range(2, int(sqrt(p))+1)] ]
一个需求演示
假如有列表:
books=[
{"name":"C#从入门到精通","price":23.7,"store":"卓越"},
{"name":"ASP.NET高级编程","price":44.5,"store":"卓越"},
{"name":"C#从入门到精通","price":24.7,"store":"当当"},
{"name":"ASP.NET高级编程","price":45.7,"store":"当当"},
{"name":"C#从入门到精通","price":26.7,"store":"新华书店"},
{"name":"ASP.NET高级编程","price":55.7,"store":"新华书店"}
]
-
求《ASP.NET高级编程》价格最便宜的店
storename=min([b for b in books if b['name']=="ASP.NET高级编程"],key=lambda b:b['price'])["store"]
过程:先用列表解析取出《ASP.NET高级编程》的列表,通过min函数,比较字典的price键获取price最小的项。
-
求在新华书店购买两本书一样一本要花的钱
price=sum([b['price'] for b in books if b['store']=="新华书店"])
-
求列表中有几本书:
bookenames=list(set(b['name'] for b in books))
-
列表里的书都打五折
books=map(lambda b:dict(name=b['name'],price=b['price']*0.5,store=b['store']),books)
-
《C#从入门到精通》的平均价格:
avg=(lambda ls:sum(ls)/len(ls))([b['price'] for b in books if b['name']=="C#从入门到精通"])
定义一个lambda匿名函数求平均值sum(ls)/len(ls)
然后传入参数。
-
求每本书的平均价格:
book_avg=map( lambda bookname: #返回一个dictionary dict(name=bookname, #求价格平均值 avg=(lambda ls:sum(ls)/len(ls)) ([b['price'] for b in books if b['name']==bookname])), list(set([b['name'] for b in books])))
或者列表推导实现:
book_avg=[
#返回一个dictionary(name,price)
dict(name=bookname,
#求价格平均值
avg=(lambda ls:sum(ls)/len(ls))
([b['price']
for b in books if b['name']==bookname]))
for bookname in
##去重后的书名列表
list(set([b['name'] for b in books]))]
step1 要求每本书的平均价格,首先要得到共有几本书,得到去重的书名列表list(set([b['name'] for b in books]))
#去重后的书名列表.
step2 要求每一本书的均价,需要将计算均价的函数映射到每一本书上,于是
map(
#计算均价的函数,
list(set([b['name'] for b in books])) #去重后的书名列表
)
step3 计算平均价格可以参考上一个例子的方法:
func=lambda bookname:
(lambda ls:sum(ls)/len(ls))([b['price'] for b in books if b['name']==bookname])