Python 集合的遍历,推导及 filter/map/reduce 操作

借鉴于其他多数语言中集合的 map/reduce 操作,也想总结一下在 Python 中如何对集合进行 map/reduce。而不是对于 Python 集合只会用简单的 for ... in 遍历,处于之间的是 Python 的  Comprehension 操作,更倾向于译作推导; 在 Scala 中也有类似的  for-comprehension 语法。

因此本文将涉及到三个方面的知识,基本的集合遍历操作,集合的推导,与 filter/map/reduce 操作。我无法写出诸如 掌握 Python 集体看这一篇就够了 的文章,但基本由本篇出发能了解到 Python 集合的基本遍历,转换操作。其余如切片,和更多能作用于 Python 集合的函数未有提及, 请查阅相关文档。

集合的基本遍历操作

这一块主要是复习功课, 希望由此熟练掌握常用的集合遍历操作方式

基本遍历

这个 for ... in 语法可应用于 list, tuple, 和 set, 还有  range, map 等。

不过上面的语法应用于 dict 只是对 key 进行遍历

对于 dict 既然可以对 keys() 进行遍历,也就可以对值 values() 进行遍历

x.keys() 的类型是 dict_keyslist(x.keys() 可以得到所有 key 组成的 listset(x.keys() 得到相应的 set

x.values() 的类型是 dict_values。也可以用 list(x.values() 和 set(x.values() 转换为相应的 list 和 set

dict 同时遍历 key, value

map.items() 类型是 dict_items, 看下方

因为每个元素是由 (key, value) 组成的  tuple, 所以能用 for key, value 进行拆解(unpack)。

遍历时得到索引

这时候要用到 enumerate 函数

可以想像它实质遍历的是 list(enumerate(x)) 列表

它的每一个元素是由索引与值组成的  tuple, 所以用 for index, value 来拆解。

集合的推导(comprehension)

Python 也无法在 for ... in 语句中应用 if..else 条件进行元素过滤,这就要用到推导了。Comprehension 可以同时完成集合的 filter 和 map 操作,如下

它的基本语法是

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 部分加入条件

Python 中的 value1 if condition else value2 语法我比较喜欢。

Comprehension 语法同样适用于 tuple, 例如下面的代码

对字典的推导

基于前面的推导语法,我们可以应用到 dict

推导中可以有多个 for

上面得到一个 a 与 b 的笛卡尔乘积

Filter/Map/Reduce 操作

现在来到本文立意的初衷,就是为了了解 Python 的 filter/map/reduce 操作。其中 filter 和 map 是可直接使用的两个函数,reduce 是来自于 functools 模块,需用 from functools import reduce 引入。看到 functools 模块名,它里边还有不少好料。

Filter

对集合的过滤接受一个返回布尔值的 Predicate 函数,或者用内联 lambda 表达式的方式

注意 filter 之后不是直接返回的 list, 而是一个 filter 类型,要用 list(y) 转换回 list 类型。

或者用内联 lambda 的方式

filter 之后返回的虽然不是一个 list, 但是它能被用于下一轮的 filter. 可是又不能直接 for .. in 遍历 filter 类型。

输出是

<filter object at 0x100e11160>
<filter object at 0x100e11160>

Map

有了 Filter 作铺垫之后,Map 就好理解了,只需把返回 True 或 False 的过滤函数改成转换函数。

也是需用 list(y) 再转换回 list。也可以在 map 中用 lamba 表达式

Reduce

reduce 通常才是真正执行计算的过程,前面 filter 和 map 多是准备, 整理输入数据的。由集合收缩为一个值就是 reduce 操作,当然也可以收缩为一个集合类型值。

比如说 1 加到 100 的操作就可以采用  reduce 操作,reduce 时可以从一个自定义的初始值开始,也可从集合中的第一个元素开始。

Python 的 reduce 操作默认从集合的第一个元素开始,因此对空列表是不能 reduce 的,取不到第一个元素

reduce 也可以由第三个参数来提供初始值,如

reduce 方法的原型是

reduce(...)
reduce(function, sequence[, initial]) -> value

下面两个 reduce 用法是等效的

简单的  reduce 函数写成 lambda 表达式就行了。

链接:

  1. Map, Filter and Reduce
  2. Comprehensions

类别: Python. 标签: , , . 阅读(32). 订阅评论. TrackBack.

Leave a Reply

avatar