杰瑞科技汇

PythonPython的filtered函数是什么?怎么用?

filter() 是 Python 内置的一个高阶函数,它的主要作用是过滤序列(例如列表、元组等),过滤掉不符合条件的元素,返回一个迭代器,其中包含所有符合指定条件的元素。

PythonPython的filtered函数是什么?怎么用?-图1
(图片来源网络,侵删)

函数语法

filter(function, iterable)

参数详解

  1. function: 一个函数,这个函数的返回值必须是布尔值(TrueFalse)。

    • filter() 会将 iterable 中的每一个元素作为参数传递给这个 function
    • function 的返回值为 True,则该元素会被保留。
    • function 的返回值为 False,则该元素会被过滤掉。
    • 注意: function 参数是 Nonefilter() 函数会直接判断元素的“真值”(Truthiness),即,保留所有为 True 的元素,过滤掉所有为 False 的元素(如 0, False, None, , [], 等)。
  2. iterable: 一个可迭代对象,例如列表、元组、集合、字符串等。filter() 将会对这个对象中的每个元素进行筛选。

返回值

filter() 函数返回一个迭代器(iterator),而不是一个列表,迭代器是一个惰性序列,只有在需要时才会计算下一个值,这在处理大数据集时非常高效,因为它不会一次性在内存中生成所有结果。


使用示例

示例 1:使用 lambda 函数(最常见)

假设我们有一个数字列表,我们只想保留其中的偶数。

PythonPython的filtered函数是什么?怎么用?-图2
(图片来源网络,侵删)
# 原始列表
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用 lambda 定义一个判断是否为偶数的函数
# filter 会将 numbers 中的每个元素 n 传给 lambda,并检查 n % 2 == 0 是否为 True
even_numbers_iterator = filter(lambda n: n % 2 == 0, numbers)
# filter() 返回的是一个迭代器,我们不能直接打印它
# print(even_numbers_iterator)  # 输出: <filter object at 0x...>
# 为了看到结果,我们需要将迭代器转换为列表
even_numbers_list = list(even_numbers_iterator)
print(even_numbers_list)
# 输出: [2, 4, 6, 8, 10]

示例 2:使用独立的函数

如果逻辑比较复杂,我们可以先定义一个函数,然后再传给 filter()

def is_positive(n):
    """判断一个数是否为正数"""
    return n > 0
numbers = [-5, -2, 0, 1, 3, -8, 10]
# 使用定义好的函数进行过滤
positive_numbers_iterator = filter(is_positive, numbers)
# 转换为列表并打印
positive_numbers_list = list(positive_numbers_iterator)
print(positive_numbers_list)
# 输出: [1, 3, 10]

示例 3:function 参数为 None

functionNone 时,filter() 会根据元素的“真值”来过滤。

mixed_values = [0, 1, False, True, "", "hello", None, [], [1, 2], {}]
# 过滤掉所有为 "假" 的值
truthy_values_iterator = filter(None, mixed_values)
# 转换为列表并打印
truthy_values_list = list(truthy_values_iterator)
print(truthy_values_list)
# 输出: [1, True, 'hello', [1, 2]]

解释:在 Python 中,0, False, None, 空字符串 , 空列表 [], 空字典 等都被视为 False,而其他值被视为 True

示例 4:过滤字符串

我们可以用 filter() 来过滤掉字符串中的某些字符。

PythonPython的filtered函数是什么?怎么用?-图3
(图片来源网络,侵删)
sentence = "Hello, World! 123"
# 过滤掉所有非字母字符
# str.isalpha() 方法如果字符串中的所有字符都是字母则返回 True
letters_iterator = filter(str.isalpha, sentence)
# 转换为列表并打印
letters_list = list(letters_iterator)
print(letters_list)
# 输出: ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']
# 也可以重新组合成一个字符串
letters_string = "".join(letters_iterator) # 注意:上面的迭代器已经用完了,需要重新创建
letters_string = "".join(filter(str.isalpha, sentence))
print(letters_string)
# 输出: HelloWorld

filter() vs. 列表推导式

在现代 Python 编程中,对于简单的过滤任务,列表推导式 通常被认为是更 Pythonic(更符合 Python 风格)且更易读的替代方案。

让我们用列表推导式重写第一个示例:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用列表推导式
even_numbers_list = [n for n in numbers if n % 2 == 0]
print(even_numbers_list)
# 输出: [2, 4, 6, 8, 10]

对比 filter() 和列表推导式:

特性 filter() 列表推导式
可读性 对于简单的 lambda,可读性尚可;对于复杂函数,可读性好。 通常被认为更直观、更易读,特别是对于初学者。
性能 在某些情况下(特别是 Python 2),filter() 可能更快,但在 Python 3 中,性能差异通常很小。 在 Python 3 中,性能通常与 filter() 相当或更好。
灵活性 只能进行“是/否”的二元过滤。 非常灵活,可以在过滤的同时对元素进行转换。
返回类型 返回一个迭代器,是惰性求值的,节省内存。 直接返回一个列表,是立即求值的。

什么时候选择 filter()

  1. 代码可读性优先:当过滤逻辑非常复杂,用一个单独命名的函数来表示时,filter(function, iterable) 的形式可能比列表推导式更清晰。

    # 复杂逻辑用 filter + 函数
    def is_valid_user(user):
        return user.get('is_active', False) and user.get('age', 0) >= 18
    active_adult_users = filter(is_valid_user, list_of_all_users)
    # 对比列表推导式
    active_adult_users = [user for user in list_of_all_users if is_valid_user(user)]

    在这个例子中,两者可读性差别不大,甚至列表推导式可能更受欢迎。

  2. 函数式编程风格:如果你倾向于函数式编程,并且已经有了一个现成的过滤函数,filter() 是一个很好的选择。

什么时候选择列表推导式?

  1. 简单过滤:对于绝大多数简单的过滤任务,列表推导式是首选,因为它更简洁。
  2. 需要转换元素:如果你想在过滤的同时修改元素,列表推导式是唯一的选择。
    # 只能使用列表推导式
    # 获取所有偶数的平方
    even_squares = [n ** 2 for n in numbers if n % 2 == 0]
    # 输出: [4, 16, 36, 64, 100]

  • filter() 是一个用于过滤序列的强大内置函数。
  • 它接受一个函数和一个可迭代对象,返回一个迭代器。
  • 它是惰性求值的,适合处理大数据。
  • 对于大多数日常任务,列表推导式因其出色的可读性和灵活性而更受推荐。
  • 在需要复用复杂过滤逻辑或遵循特定编程风格时,filter() 仍然是一个有价值的选择。
分享:
扫描分享到社交APP
上一篇
下一篇