Python中的filter()函数如何过滤序列元素?
Python中的filter()函数是一个内置函数,用于过滤序列元素,其功能是从序列中过滤出符合条件的元素,返回满足条件的元素列表。filter()函数的原型为filter(function, iterable),其中function为一个函数,用于判断序列中每个元素是否符合条件。iterable为一个序列,可以是列表、元组、字符串等迭代对象。
filter()函数的用法非常简单,其返回值是一个迭代器对象,可以使用list()函数将其转换为列表。我们可以在function函数中对iterable序列进行操作,返回True或False,True表示过滤出该元素,False则不过滤。
下面是filter()函数的语法格式:
filter(function, iterable)
其中,function为一个函数,意义如下:
- function接收一个参数,并返回True或False。
- 参数可以是任何可迭代的对象,包括列表、元组、集合、字典等。
下面是一个简单的例子来说明filter()函数的使用方法。
假设我们有一个包含数字的列表,现在要过滤出其中的偶数,可以使用下面的代码:
# 过滤出偶数 nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] even = filter(lambda x: x % 2 == 0, nums) print(list(even))
运行上面的代码,输出的结果为:
[2, 4, 6, 8, 10]
在以上的例子中,我们定义了一个lambda函数,用来判断每个元素是否为偶数。通过filter()函数进行过滤,最后将结果转换为列表并输出。
除了使用lambda函数外,我们还可以定义一个普通的函数来完成过滤操作。以下是一个使用自定义函数的例子:
# 定义一个自定义函数用来过滤
def is_even(n):
return n % 2 == 0
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even = filter(is_even, nums)
print(list(even))
运行以上代码,输出的结果和之前是一样的:
[2, 4, 6, 8, 10]
除了上述的简单例子之外,filter()函数还有一些更灵活的用法,下面来看一下。
filter()函数的高级用法
1. 使用filter()过滤空字符串
假设我们有一个包含多个字符串的列表,现在需要过滤掉其中的空字符串,可以使用下面的代码:
# 过滤空字符串 strs = ["hello", "", "world", "", "python"] non_empty_strs = filter(None, strs) print(list(non_empty_strs))
运行以上代码,输出的结果为:
['hello', 'world', 'python']
在这个例子中,我们使用的是内置函数None作为过滤条件,它会根据元素的真假值进行过滤。当元素为False、0、空字符串等时都会被过滤掉,非空字符串、数字、布尔值等则不会被过滤。
2. 数据筛选和转换
假设我们有一个包含学生信息的列表,每个元素是一个字典,现在需要将其中年龄小于18岁的学生的姓名提取出来,可以使用下面的代码:
# 筛选出年龄小于18岁的学生姓名
students = [
{"name": "Tom", "age": 19},
{"name": "Jerry", "age": 16},
{"name": "Tony", "age": 15},
{"name": "Mike", "age": 18},
{"name": "Alice", "age": 20},
]
young_students = filter(lambda s: s['age'] < 18, students)
names = map(lambda s: s['name'], young_students)
print(list(names))
运行以上代码,输出的结果为:
['Jerry', 'Tony']
在这个例子中,我们使用了map()函数对young_students列表中的元素进行了转换。map()函数的定义如下:
map(function, iterable)
map()函数和filter()函数很类似,但它会对序列中的每个元素应用function函数,并返回由每个元素应用函数后的结果所组成的新列表。具体来说,map()函数会将iterable序列中的每个元素传递给function函数,并返回function函数的返回值所组成的列表。
在以上的例子中,我们先使用filter()函数对学生信息进行筛选,得到一个包含年龄小于18岁的学生字典组成的列表,然后使用map()函数将学生字典列表转换成只包含学生姓名的列表。
3. 使用filter()和reduce()实现素数筛法
素数筛法是一种用于查找素数的算法,它的基本思想是从2开始依次枚举整数,将每个数的倍数都标记为合数,最终剩余的数就是素数。
下面是使用filter()和reduce()函数实现素数筛法的代码:
import itertools
from functools import reduce
def primes():
# 生成一个从2开始的无限迭代器
numbers = itertools.count(2)
while True:
# 取出当前数
prime_number = next(numbers)
# 以当前数为因子去筛
numbers = filter(lambda x, p=prime_number: x % p != 0 or x == p, numbers)
# 输出当前数
yield prime_number
def prime_numbers(limit):
# 取出limit以内的所有素数
prime_list = []
for p in primes():
if p > limit:
break
prime_list.append(p)
return prime_list
print(prime_numbers(100))
运行以上代码,输出的结果为:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
在以上的代码中,我们使用了Python中的itertools模块和functools模块。itertools.count()函数用于生成一个从2开始的无限迭代器。在while True循环中,我们先使用next()函数取出当前的素数,然后使用filter()函数筛选掉所有的合数,最终得到一个包含了所有素数的迭代器。至于reduce()函数,这个函数用于对一个序列进行累积计算,需要带有一个参数function,用于指定该计算的操作,reduce()函数的定义如下:
reduce(function, sequence[, initial])
在以上的代码中,我们没有直接使用reduce()函数,而是将其作为内建函数使用的,即从functools模块中引入,最终通过调用primes()函数和prime_numbers()函数,实现了素数筛法程序。
总结
filter()函数是Python中强大的过滤函数之一,它可以过滤出符合条件的元素,返回合法的元素组成的列表。在使用filter()函数时,我们可以使用lambda函数或自定义函数来对序列进行过滤。除此之外,filter()函数还可以结合map()函数和reduce()函数,完成更复杂的过滤操作。无论是基本的还是复杂的用法,都可以让我们轻松实现过滤序列的操作,提高 Python 编码的效率和代码的可读性。
