python内置函数 filter() map() 与 列表推导式

129 阅读3分钟

python内置函数 filter() map() 与 列表推导式

概念与示例

内置函数filter()map()

Python 中的 filter()map() 是两个内置的高阶函数,它们都用于对可迭代对象进行操作,但它们的目的和用法有所不同。

filter() 函数:

filter() 函数用于过滤序列,返回一个迭代器。它接受两个参数:一个函数和一个序列。传入的函数用于判断序列中的每个元素是否满足条件,返回 TrueFalsefilter() 会返回所有使得函数返回 True 的元素。

语法:

filter(function, iterable)

例子:

numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # 输出: [2, 4, 6]

map() 函数:

map() 函数用于将一个函数应用于序列的每个元素。它同样接受两个参数:一个函数和一个序列。map() 会返回一个迭代器,迭代器中的元素是将传入的函数应用于原始序列的每个元素的结果。

语法:

map(function, iterable, ...)

例子:

numbers = [1, 2, 3, 4, 5, 6]
squares = map(lambda x: x ** 2, numbers)
print(list(squares))  # 输出: [1, 4, 9, 16, 25, 36]

差异点:

  • filter() 用于筛选,保留满足条件的元素。
  • map() 用于转换,对每个元素应用函数后返回结果。
  • filter() 返回的是条件筛选后的元素集合,map() 返回的是应用函数后的元素集合。
  • filter() 需要一个布尔函数作为参数,而 map() 需要一个对每个元素进行操作的函数。
  • 两者都返回迭代器,需要用 list() 转换为列表或其他形式以查看全部元素。

列表推导式

Python 的列表推导式(List Comprehension)是一种简洁的构建列表的方法,它允许你用一行代码代替传统的多行循环和条件语句。列表推导式不仅使代码更加简洁,而且通常比等价的循环代码执行得更快。

列表推导式的一般形式如下:

[expression for item in iterable if condition]
  • expression 是对每个元素进行操作的表达式。
  • item 是从 iterable 中迭代出来的元素。
  • iterable 是一个可迭代对象,比如列表、元组、字典等。
  • condition 是一个可选的条件语句,用于过滤迭代出的元素。

例子:

基本列表推导式:

squares = [x**2 for x in range(10)]  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

带条件的列表推导式:

even_squares = [x**2 for x in range(10) if x % 2 == 0]  # [0, 4, 16, 36, 64]

嵌套列表推导式:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

使用函数:

from math import sqrt
roots = [sqrt(x**2) for x in range(-5, 6)]  # [5.0, 4.47213595, 3.46410162, 2.82842712, 2.0, 1.41421356, 1.0, 0.70709858, 0.5, 0.31622777]

字典推导式:

虽然不是列表推导式,但字典推导式使用相似的语法:

squared_dict = {x: x**2 for x in range(5)}  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

列表推导式是 Python 中一个非常强大的特性,它使得代码更加易读和高效。

两者的区别

代码中使用列表推导式和filter/map组合创建相同的列表,效果如下:

>>> symbols = '$¢£¥€¤'
>>> beyond_ascii = [ord(s) for s in symbols if ord(s) > 127]
>>> beyond_ascii
[162, 163, 165, 8364, 164]
>>> beyond_ascii = list(filter(lambda c: c > 127, map(ord, symbols)))
>>> beyond_ascii
[162, 163, 165, 8364, 164]

从效果来看,filter和map合起来能做的事情,列表推导也可以做,而且还不需要借助难以理解和阅读的lambda表达式。因此在 Python 3 中推荐使用列表推导式