Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1029413
  • 博文数量: 164
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1336
  • 用 户 组: 普通用户
  • 注册时间: 2016-03-11 14:13
个人简介

狂甩酷拽吊炸天

文章分类

全部博文(164)

文章存档

2023年(1)

2022年(3)

2021年(4)

2020年(17)

2019年(37)

2018年(17)

2017年(35)

2016年(50)

分类: Python/Ruby

2017-05-15 13:37:22

python的map,reduce,filter,lambda,和排序

lambda

lambda用来编写简单的函数

lambda的使用方法如下:lambda arg1 ,arg2,arg3,...,argn : expression


fs = [(lambda n, i=i : i + n) for i in range(10)]
>>> fs[3](4)
7
>>> fs[4](4)
8
>>> fs[5](4)
9


filter

filter,map,reduce都是python的内建函数, filter与map较简单,都是对列表中值依次处理,输出结果也是列表。reduce则是依次把列别中的值两两作为参数,输入到函数中,结果未必是列表。


>>>filter(lambda x : x%2 == 0,[1,2,3,4,5])

[2, 4]


>>> map(lambda x : x * 2,[1,2,3,4,[5,6,7]])
[2, 4, 6, 8, [5, 6, 7, 5, 6, 7]]



map:
def add100(x): return x + 100 >> > hh

= [11, 22, 33]
>> > map(add100, hh)
[111, 122, 133] 就像文档中说的:对hh中的元素做了add100,返回了结果的list如果给出了额外的可迭代参数,则对每个可迭代参数中的元素并行的应用‘function’。(翻译的不好,这里的关键是并行 >> > def abc(a, b, c):
    ... return a * 10000 + b * 100 + c


...
>> > list1 = [11, 22, 33]
>> > list2 = [44, 55, 66]
>> > list3 = [77, 88, 99]
>> > map(abc, list1, list2, list3)
[114477, 225588, 336699] 看到并行的效果了吧!在每个list中,取出了下标相同的元素,执行了abc()如果 'function' 给出的是None,自动假定一个‘identity’函数(这个‘identity’不知道怎么解释,看例子吧)  >> > list1 = [11, 22, 33]
>> > map(None, list1)
[11, 22, 33]
>> > list1 = [11, 22, 33]
>> > list2 = [44, 55, 66]
>> > list3 = [77, 88, 99]
>> > map(None, list1, list2, list3)
[(11, 44, 77), (22, 55, 88), (33, 66, 99)] 用语言解释好像有点拗口 ,例子应该很容易理解。 有人说可以这样理解map()   map(f, iterable) 基本上等于: [f(x) for x in iterable] 赶快试一下:  >> > def add100(x):
    ... return x + 100...

>> > list1 = [11, 22, 33]
>> > map(add100, list1)
[101, 102, 103]

>> > [add100(i) for i in list1]
[101, 102, 103] 哦,输出结果一样。原来map() 就是列表推导式啊!要是这样想就错了:这里只是表面现象!再来个例子看看:  >> > def abc(a, b, c):
    ... return a * 10000 + b * 100 + c


...
>> > list1 = [11, 22, 33]
>> > list2 = [44, 55, 66]
>> > list3 = [77, 88, 99]
>> > map(abc, list1, list2, list3)
[114477, 225588, 336699] 这个例子我们在上面看过了,若是用列表推导应该怎么写呢?我想是这样的:   [abc(a, b, c) for a in list1 for b in list2 for c in list3] 但是看到结果,发现根本不是这么回事:  [114477, 114488, 114499, 115577, 115588, 115599, 116677, 116688, 116699, 224477, 224488, 224499, 225577, 225588, 225599, 226677, 226688, 226699, 334477, 334488, 334499, 335577, 335588, 335599, 336677, 336688, 336699] 这便是上面列表推导的结果。怎么会这么多?当然了列表推导可以这么写:      result = [] for a in list1: for b in list2: for c in list3:
    result.append(abc(abc)) 原来如此,若是将三个list看做矩阵的话:


11
22
33
44
55
66
77
88
99

map()只做了列上面的运算,而列表推导(也就是嵌套for循环)做了笛卡尔乘积。

OK,就写到这里。仅个人理解,如有差错请指正,多谢!



reduce的实现

1
2
3
4
5
6
7
8
9
def reduce(bin_func,seq,initial=None):
   lseq = list(seq)
   if initial is None:
       res = lseq.pop(0)
   else:
       res = initial
   for eachItem in lseq:
       res = bin_func(res,eachItem)
   return res

>>> reduce(lambda x,y : x + y,[1,2,3,4])
10
>>> reduce(lambda x,y : x + y,[1,2,3,4],10)
20


第一次调用function时,如果提供initial参数,会以sequence中的第一个元素和initial作为参数调用function,否则会以序列sequence中的前两个元素做参数调用function。
reduce(lambda x, y: x + y, [2, 3, 4, 5, 6], 1)
结果为21(  (((((1+2)+3)+4)+5)+6)  )
reduce(lambda x, y: x + y, [2, 3, 4, 5, 6])
结果为20


另外注意:filter,map有时候可以被列表解析替代,而且列表解析更强大

a=[x*2 for x in range(10)]

a=[x for x in range(10) if x%3==0]

[x+y for x in range(5) if x%2 == 0 for y in range(10) if y%2 ==1] ,列表解析可以两层循环

list排序

list排序有两种方法,一是使用list的成员函数,二是使用内建函数sorted。

list的成员函数有3个参数list.sort(cmp=None, key=None, reverse=False)

三个参数的说明如下:

cmp和key都是函数,

key是一个变量的函数,输入为list中的一个element,输出为一个可比较的element

cmp是两个边路的函数,输入为list重两个element,输出为这两个element的大小关系(大于0,小于0,等于0)

key与cmp往往不会同时使用

下面是使用例子:

实例1:
>>>L = [2,3,1,4]
>>>L.sort()
>>>L
>>>[1,2,3,4]
实例2:
>>>L = [2,3,1,4]
>>>L.sort(reverse=True)
>>>L
>>>[4,3,2,1]
实例3:
>>>L = [('b',2),('a',1),('c',3),('d',4)]
>>>L.sort(cmp=lambda x,y:cmp(x[1],y[1]))
>>>L
>>>[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
实例4:
>>>L = [('b',2),('a',1),('c',3),('d',4)]
>>>L.sort(key=lambda x:x[1])
>>>L
>>>[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
实例5:
>>>L = [('b',2),('a',1),('c',3),('d',4)]
>>>import operator
>>>L.sort(key=operator.itemgetter(1))
>>>L
>>>[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
实例6:(DSU方法:Decorate-Sort-Undercorate)
>>>L = [('b',2),('a',1),('c',3),('d',4)]
>>>A = [(x[1],i,x) for i,x in enumerate(L)] #i can confirm the stable sort
>>>A.sort()
>>>L = [s[2] for s in A]
>>>L
>>>[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
以上给出了6中对List排序的方法,其中实例3.4.5.6能起到对以List item中的某一项
为比较关键字进行排序.
效率比较:
cmp < DSU < key
通过实验比较,方法3比方法6要慢,方法6比方法4要慢,方法4和方法5基本相当
多关键字比较排序:
实例7:
>>>L = [('d',2),('a',4),('b',3),('c',2)]
>>> L.sort(key=lambda x:x[1])
>>> L
>>>[('d', 2), ('c', 2), ('b', 3), ('a', 4)]
我们看到,此时排序过的L是仅仅按照第二个关键字来排的,如果我们想用第二个关键字
排过序后再用第一个关键字进行排序呢?有两种方法
实例8:
>>> L = [('d',2),('a',4),('b',3),('c',2)]
>>> L.sort(key=lambda x:(x[1],x[0]))
>>> L
>>>[('c', 2), ('d', 2), ('b', 3), ('a', 4)]
实例9:
>>> L = [('d',2),('a',4),('b',3),('c',2)]
>>> L.sort(key=operator.itemgetter(1,0))
>>> L
>>>[('c', 2), ('d', 2), ('b', 3), ('a', 4)]
为什么实例8能够工作呢?原因在于tuple是的比较从左到右比较的,比较完第一个,如果
相等,比较第二个

====================================================================

python中pass含义:不做任何处理。

阅读(1166) | 评论(0) | 转发(0) |
0

上一篇:python pipe模块用法

下一篇:SSL工作原理

给主人留下些什么吧!~~