内容简介:借鉴于其他多数语言中集合的 map/reduce 操作,也想总结一下在 Python 中如何对集合进行 map/reduce。而不是对于 Python 集合只会用简单的因此本文将涉及到三个方面的知识,基本的集合遍历操作,集合的推导,与 filter/map/reduce 操作。我无法写出诸如 掌握 Python 集体看这一篇就够了 的文章,但基本由本篇出发能了解到 Python 集合的基本遍历,转换操作。其余如切片,和更多能作用于 Python 集合的函数未有提及, 请查阅相关文档。这一块主要是复习功课,
借鉴于其他多数语言中集合的 map/reduce 操作,也想总结一下在 Python 中如何对集合进行 map/reduce。而不是对于 Python 集合只会用简单的 for ... in
遍历,处于之间的是 Python 的 Comprehension 操作,更倾向于译作推导; 在 Scala 中也有类似的 for-comprehension
语法。
因此本文将涉及到三个方面的知识,基本的集合遍历操作,集合的推导,与 filter/map/reduce 操作。我无法写出诸如 掌握 Python 集体看这一篇就够了 的文章,但基本由本篇出发能了解到 Python 集合的基本遍历,转换操作。其余如切片,和更多能作用于 Python 集合的函数未有提及, 请查阅相关文档。
集合的基本遍历操作
这一块主要是复习功课, 希望由此熟练掌握常用的集合遍历操作方式
基本遍历
for a in [1, 2, 3]: print(a)
这个 for ... in
语法可应用于 list
, tuple
, 和 set
, 还有 range
, map
等。
不过上面的语法应用于 dict
只是对 key
进行遍历
x = {"a": 1, "b": 2} for key in x: # 这里相当于是 for key in dict.keys(): print(key, "=>", x['key'])
对于 dict 既然可以对 keys()
进行遍历,也就可以对值 values()
进行遍历
x = {"a": 1, "b": 2} for value in x.values(): print(value) # 依次输出 1, 2
x.keys()
的类型是 dict_keys
, list(x.keys()
可以得到所有 key 组成的 list
。 set(x.keys()
得到相应的 set
x.values()
的类型是 dict_values
。也可以用 list(x.values()
和 set(x.values()
转换为相应的 list
和 set
对 dict
同时遍历 key, value
map = {"a": 1, "b": 2} for key, value in map.items(): print(key, "=>", value)
map.items()
类型是 dict_items
, 看下方
>>> map.items() dict_items([('a', 1), ('b', 2)]) >>> list(map.items()) [('a', 1), ('b', 2)] >>> set(map.items()) {('b', 2), ('a', 1)}
因为每个元素是由 (key, value) 组成的 tuple
, 所以能用 for key, value
进行拆解(unpack)。
遍历时得到索引
这时候要用到 enumerate
函数
x = [1, 5, 3] for index, value in enumerate(x): print(index, "=>", value)
可以想像它实质遍历的是 list(enumerate(x))
列表
>>> list(enumerate(x)) [(0, 1), (1, 5), (2, 3)]
它的每一个元素是由索引与值组成的 tuple
, 所以用 for index, value
来拆解。
集合的推导(comprehension)
Python 也无法在 for ... in
语句中应用 if..else
条件进行元素过滤,这就要用到推导了。Comprehension 可以同时完成集合的 filter
和 map
操作,如下
x = [1, 5, 3] y = [val * 2 for val in x] # x 中每个元素乘以 2 得到新的列表 [2, 10, 6] z = [val * 2 for val in x if val > 2] # x 中大于 2 的元素诚以 2 得到新的列表 [10, 6]
它的基本语法是
new_list = [expression for variable in old_list if expression]
new_dict = {key_expression: value_expression for variable in list if expression}
new_tuple = (expression for variable in old_tuple if expression) # 其中 old_tuple 也可以是 list
在 expression 部分加入条件
x = [1, 2, 3, 4] >>> x = [1, 2, 3, 4] >>> y = [True if val % 2 == 0 else False for val in x] >>> y [False, True, False, True]
Python 中的 value1 if condition else value2
语法我比较喜欢。
Comprehension 语法同样适用于 tuple
, 例如下面的代码
>>> a = (1, 3, 5) >>> b = (val + 2 for val in a) >>> list(b) [3, 5, 7]
对字典的推导
基于前面的推导语法,我们可以应用到 dict
上
>>> x = {"a": 1, "b": 5, "c": 3} >>> y = {key: value + 2 for key, value in x.items()} >>> y {'a': 3, 'b': 7, 'c': 5} >>> z = {key + "0": value + 2 for key, value in x.items() if value > 2} >>> z {'b0': 7, 'c0': 5}
推导中可以有多个 for
>>> a = [1, 3, 5] >>> b = [2, 4, 6] >>> x = [v1 * v2 for v1 in a for v2 in b] >>> x [2, 4, 6, 6, 12, 18, 10, 20, 30]
上面得到一个 a 与 b 的笛卡尔乘积
Filter/Map/Reduce 操作
现在来到本文立意的初衷,就是为了了解 Python 的 filter/map/reduce 操作。其中 filter
和 map
是可直接使用的两个函数, reduce
是来自于 functools
模块,需用 from functools import reduce
引入。看到 functools
模块名,它里边还有不少好料。
Filter
对集合的过滤接受一个返回布尔值的 Predicate 函数,或者用内联 lambda 表达式的方式
>>> x = [1, 3, 2, 5] >>> def greater_then_2(val): return val > 2 >>> y = filter(greater_then_2, x) >>> y <filter object at 0x1071f8048> >>> list(y) [3, 5]
注意 filter
之后不是直接返回的 list
, 而是一个 filter
类型,要用 list(y)
转换回 list
类型。
或者用内联 lambda 的方式
>>> x = [1, 3, 2, 5] >>> y = filter(lambda a: a > 2, x) >>> list(y) [3, 5] >>> z = filter(lambda a: a > 2, filter(lambda a: a > 2, x)) >>> list(z) [3, 5]
filter
之后返回的虽然不是一个 list
, 但是它能被用于下一轮的 filter
. 可是又不能直接 for .. in
遍历 filter
类型。
for val in y: print(y)
输出是
<filter object at 0x100e11160> <filter object at 0x100e11160>
Map
有了 Filter 作铺垫之后,Map 就好理解了,只需把返回 True 或 False 的过滤函数改成转换函数。
>>> x = [1, 3, 2, 5] >>> def plus_1(val): return val + 1 >>> y = map(plus_1, x) >>> y <map object at 0x1074b9160> >>> list(y) [2, 4, 3, 6]
也是需用 list(y)
再转换回 list。也可以在 map 中用 lamba 表达式
y = map(lambda a: a + 1, x)
Reduce
reduce
通常才是真正执行计算的过程,前面 filter
和 map
多是准备, 整理输入数据的。由集合收缩为一个值就是 reduce
操作,当然也可以收缩为一个集合类型值。
比如说 1 加到 100 的操作就可以采用 reduce
操作,reduce 时可以从一个自定义的初始值开始,也可从集合中的第一个元素开始。
>>> from functools import reduce >>> numbers = range(1, 101) # 下面直接对 range 进行 reduce 操作 >>> def add(m, x): # m 代表每次累加后的结果,x 是当前遍历到的元素 return m + x >>> >>> y = reduce(add, numbers) >>> y 5050
Python 的 reduce
操作默认从集合的第一个元素开始,因此对空列表是不能 reduce
的,取不到第一个元素
>>> y = reduce(add, []) Traceback (most recent call last): File "<pyshell#48>", line 1, in <module> y = reduce(add, []) TypeError: reduce() of empty sequence with no initial value
reduce
也可以由第三个参数来提供初始值,如
>>> y = reduce(add, [], 100) >>> y 100
reduce
方法的原型是
reduce(...) reduce(function, sequence[, initial]) -> value
下面两个 reduce
用法是等效的
reduce(function, sequence) reduce(function, sequence[1:], sequence[0]
简单的 reduce
函数写成 lambda 表达式就行了。
链接:
以上所述就是小编给大家介绍的《Python 集合的遍历,推导及 filter/map/reduce 操作》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Beginning ASP.NET 4 in C# and Vb
Imar Spaanjaars / Wrox / 2010-3-19 / GBP 29.99
This book is for anyone who wants to learn how to build rich and interactive web sites that run on the Microsoft platform. With the knowledge you gain from this book, you create a great foundation to ......一起来看看 《Beginning ASP.NET 4 in C# and Vb》 这本书的介绍吧!