美文网首页
Python学习笔记(三)

Python学习笔记(三)

作者: normantian | 来源:发表于2016-03-31 18:10 被阅读0次

三个内置函数 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])

相关文章

网友评论

      本文标题:Python学习笔记(三)

      本文链接:https://www.haomeiwen.com/subject/zdnelttx.html