filter()函数是Python中一个灵活且强大的工具,它能够处理和筛选来自不同可迭代对象(如列表、元组和集合)的数据。本教程将从基础用法到涉及自定义函数和lambda表达式的复杂情况,详细讲解Python的过滤特性,旨在帮助初学者和经验丰富的程序员掌握这一功能。
filter()函数可以根据给定的函数标准,从可迭代对象(如列表、元组或集合)中创建一个迭代器,该函数返回true的元素。filter()的主要目的是根据函数提供的标准移除元素。
语法如下:
filter(function, iterable)
其中:
function
:一个测试可迭代对象中每个元素并返回true或false的函数。iterable
:要被过滤的可迭代对象(例如列表、元组、集合)。filter()方法返回一个迭代器(filter类型),可以被转换成列表、元组或集合。
关键点:
让从一个基本示例开始,以了解filter()如何工作:
# 定义一个函数检查数字是否为偶数
def is_even(num):
return num % 2 == 0
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用filter()获取偶数
even_numbers = filter(is_even, numbers)
# 将filter对象转换为列表
even_numbers_list = list(even_numbers)
print(even_numbers_list)
输出:
[2, 4, 6, 8, 10]
在这个例子中,函数is_even
确定给定的数字是否为偶数。为了从numbers
列表中排除偶数整数,filter()函数利用is_even
。
为了生成匿名且简洁的函数,也可以使用lambda函数作为filter()的第一个参数。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用filter()与lambda函数获取奇数
odd_numbers = filter(lambda x: x % 2 != 0, numbers)
# 将filter对象转换为列表
odd_numbers_list = list(odd_numbers)
print(odd_numbers_list)
输出:
[1, 3, 5, 7, 9]
在这个例子中,使用lambda表达式来创建一个匿名函数,该函数用于检查数字是否为奇数。
字符串也可以使用filter()函数根据条件进行过滤。
# 定义一个函数检查字符是否为元音
def is_vowel(char):
return char.lower() in 'aeiou'
sentence = "Hello, World!"
# 使用filter()从句子中获取元音
vowels = filter(is_vowel, sentence)
# 将filter对象转换为列表
vowels_list = list(vowels)
print(vowels_list)
输出:
['e', 'o', 'o']
在这个例子中,函数is_vowel
确定给定的字符是否为元音。为了从sentence
中排除元音字符,filter()函数利用is_vowel
。
可以使用filter()创建更复杂的过滤条件。让根据多个标准过滤一个字典列表。
students = [
{"name": "Alice", "grade": 85},
{"name": "Bob", "grade": 72},
{"name": "Charlie", "grade": 90},
{"name": "Dave", "grade": 68},
{"name": "Eve", "grade": 95}
]
# 定义一个函数过滤成绩大于或等于80的学生
def is_passing(student):
return student["grade"] >= 80
# 使用filter()获取及格的学生
passing_students = filter(is_passing, students)
# 将filter对象转换为列表
passing_students_list = list(passing_students)
print(passing_students_list)
输出:
[{'name': 'Alice', 'grade': 85}, {'name': 'Charlie', 'grade': 90}, {'name': 'Eve', 'grade': 95}]
在这个例子中,函数is_passing
确定给定的学生是否及格。为了从students
列表中排除不及格的学生,filter()函数利用is_passing
。
为了说明一个更复杂的情况,从基于每个元组的第一个元素的列表中过滤出唯一的元素。
data = [(1, 'a'), (2, 'b'), (1, 'c'), (3, 'd'), (2, 'e')]
# 定义一个函数基于元组的第一个元素过滤唯一元素
def unique_first_elements(seq):
seen = set()
for item in seq:
if item[0] not in seen:
seen.add(item[0])
yield item
# 使用filter()与unique_first_elements生成器函数
unique_data = unique_first_elements(data)
# 将生成器转换为列表
unique_data_list = list(unique_data)
print(unique_data_list)
输出:
[(1, 'a'), (2, 'b'), (3, 'd')]
在这个例子中,函数unique_first_elements
确定给定的元组是否基于其第一个元素是唯一的。为了从data
列表中排除重复的元素,filter()函数利用unique_first_elements
。
现在让看一些使用filter()函数的练习题。
过滤正数:
def filter_positive_numbers(numbers):
return list(filter(lambda x: x > 0, numbers))
# 测试函数
numbers = [-10, -5, 0, 5, 10]
positive_numbers = filter_positive_numbers(numbers)
print(positive_numbers)
输出:
[5, 10]
过滤回文数:
def filter_palindromes(words):
return list(filter(lambda word: word == word[::-1], words))
# 测试函数
words = ["level", "world", "radar", "python", "madam"]
palindromic_words = filter_palindromes(words)
print(palindromic_words)
输出:
['level', 'radar', 'madam']
过滤自定义对象:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"{self.name} ({self.age})"
def filter_persons_over_30(persons):
return list(filter(lambda person: person.age <= 30, persons))
# 测试函数
people = [
Person("Alice", 25),
Person("Bob", 35),
Person("Charlie", 30),
Person("Dave", 40),
Person("Eve", 28)
]
filtered_people = filter_persons_over_30(people)
print(filtered_people)
输出:
[Alice (25), Charlie (30), Eve (28)]