Python 中的 in:成员运算符详解

学习如何在 Python 中使用 in 运算符进行成员测试,包括列表、元组、字符串、集合和字典的语法示例、性能提示和最佳实践。

in 运算符是 Python 的成员运算符,用于检查值是否存在于集合中,如列表、元组、字符串、集合或字典。如果找到值则返回 True,否则返回 False。此运算符使成员测试变得简洁易读。

in 运算符的作用是什么?

in 运算符执行成员测试:它在集合中搜索给定值并返回布尔结果。基本语法是:

value in collection

这里,value 是您要查找的值,collection 可以是任何可迭代对象,如列表、元组、字符串、集合或字典(对于字典,in 默认检查键)。

在列表和元组中使用 in

列表和元组是 in 运算符最常见的用例。

示例 1:检查列表中的成员

numbers = [1, 2, 3, 4, 5]

print(3 in numbers)      # Output: True
print(10 in numbers)     # Output: False
print(3 not in numbers)  # Output: False
输出:
True
False
False

示例 2:检查元组中的成员

coordinates = (10, 20, 30)

print(20 in coordinates)      # Output: True
print(50 in coordinates)      # Output: False
print(50 not in coordinates)  # Output: True
输出:
True
False
True

对于列表和元组,Python 使用线性搜索算法,这意味着它会逐个检查每个元素,直到找到匹配项或到达末尾。时间复杂度为 O(n),因此较大的集合需要更长的搜索时间。

在字符串中使用 in

当与字符串一起使用时,in 运算符检查子字符串成员

示例 1:基本子字符串检查

text = "Hello, World!"

print("World" in text)      # Output: True
print("Python" in text)     # Output: False
print("hello" in text)      # Output: False (case-sensitive)
输出:
True
False
False

示例 2:不区分大小写的检查

text = "Hello, World!"
search = "world"

print(search.lower() in text.lower())  # Output: True
输出:
True

字符串成员测试区分大小写。如果您需要不区分大小写的检查,请将两个字符串转换为相同的大小写。Python 字符串中的子字符串搜索在最坏情况下也具有 O(n) 复杂度。

在集合中使用 in

集合针对成员测试进行了优化。由于集合内部使用哈希表in 运算符的平均时间复杂度为 O(1)

示例 1:快速成员检查

allowed_users = {"alice", "bob", "charlie"}

print("alice" in allowed_users)    # Output: True
print("dave" in allowed_users)     # Output: False
输出:
True
False

示例 2:性能优化

# Slow for large lists
users = ["alice", "bob", "charlie"]
if "alice" in users:
    print("Found")

# Fast - convert to set first
users_set = set(users)
if "alice" in users_set:
    print("Found")
输出:
Found
Found

如果您需要执行多次成员检查,先将列表转换为集合可以显著提高性能。

在字典中使用 in

当您将 in 与字典一起使用时,它检查键是否存在(不是值)。

示例 1:检查键

user_ages = {"alice": 30, "bob": 25, "charlie": 35}

print("alice" in user_ages)      # Output: True
print("dave" in user_ages)       # Output: False
print(30 in user_ages)           # Output: False (30 is a value, not a key)
输出:
True
False
False

示例 2:检查值

user_ages = {"alice": 30, "bob": 25, "charlie": 35}

# Check if a value exists
print(30 in user_ages.values())  # Output: True
输出:
True

示例 3:检查键值对

user_ages = {"alice": 30, "bob": 25, "charlie": 35}

# Check if a key-value pair exists
print(("alice", 30) in user_ages.items())  # Output: True
输出:
True

字典的键成员测试平均也是 O(1),因为字典使用哈希表。

not in 运算符

Python 还提供 not in 运算符,如果未找到值则返回 True

示例:使用 not in

numbers = [1, 2, 3, 4, 5]

print(10 not in numbers)  # Output: True
print(3 not in numbers)   # Output: False
输出:
True
False

这只是 in 的逻辑否定,它适用于所有相同的数据类型。

在自定义对象中使用 in

如果您创建自己的类,可以通过实现 __contains__() 方法使它们与 in 运算符一起工作。

示例:自定义集合类

class MyCollection:
    def __init__(self, items):
        self.items = items
    
    def __contains__(self, item):
        return item in self.items

my_list = MyCollection([1, 2, 3, 4, 5])

print(3 in my_list)   # Output: True
print(10 in my_list)  # Output: False
输出:
True
False

如果您的类未定义 __contains__() 但可迭代(实现 __iter__()),Python 将回退到遍历集合来检查成员资格。

性能考虑

in 运算符的性能取决于数据类型。

数据类型 时间复杂度 备注
List O(n) Linear search
Tuple O(n) Linear search
String O(n) Substring search
Set O(1) average Hash-based lookup
Dictionary O(1) average Hash-based lookup (keys only)

对于大型集合的频繁成员检查,优先使用集合或字典而不是列表或元组。

常见用例

用例 1:检查用户权限

admin_users = {"alice", "bob"}

if current_user in admin_users:
    print("Access granted")
else:
    print("Access denied")
输出:
Access granted

用例 2:验证输入

valid_options = ["yes", "no", "maybe"]

user_input = input("Enter your choice: ")

if user_input in valid_options:
    print("Valid choice")
else:
    print("Invalid choice")
输出:
Valid choice

用例 3:过滤数据

exclude_words = {"the", "is", "at", "which", "on"}

words = ["the", "quick", "brown", "fox"]
filtered = [word for word in words if word not in exclude_words]

print(filtered)  # Output: ['quick', 'brown', 'fox']
输出:
['quick', 'brown', 'fox']

常见错误和最佳实践

错误 1:使用 in 进行范围检查

# Not recommended for performance-critical code
if 5 in range(1, 10):
    print("In range")

# Better: Use comparison operators
if 1 <= 5 < 10:
    print("In range")

不要在性能关键的代码中使用 in 进行数值范围检查,如 if 5 in range(1, 10):;请改用比较运算符:if 1 <= 5 < 10:

实践 1:将列表转换为集合以进行频繁检查

# When checking membership in large lists repeatedly
large_list = [1, 2, 3, ...]  # Many items

# Convert to set for faster lookups
large_set = set(large_list)
if item in large_set:
    print("Found")

当重复检查大型列表中的成员资格时,先将列表转换为集合可以大大提高查找速度。

实践 2:记住字典行为

user_data = {"name": "Alice", "age": 30}

# in checks keys, not values
print("name" in user_data)        # True
print("Alice" in user_data)        # False

# To check values, use .values()
print("Alice" in user_data.values())  # True

请记住,in 检查字典中的,而不是值。如果您需要检查值或键值对,请使用 .values().items()

实践 3:字符串中的大小写敏感性

text = "Hello, World!"

# Case-sensitive check
print("hello" in text)  # False

# Case-insensitive check
print("hello".lower() in text.lower())  # True

使用 in 的字符串成员测试区分大小写;如果需要,请规范化大小写。

自己试试

通过修改下面的代码来练习您学到的知识。尝试更改值和条件以查看不同的输出!

就绪
main.py
输出控制台 0 ms
// 点击"运行代码"查看结果

相关主题

常见问题

'in' 和 '==' 在 Python 中有什么区别?

in 运算符检查值是否存在于集合中(成员测试),而 == 检查两个值是否相等。例如,3 in [1, 2, 3] 返回 True(成员资格),而 [1, 2, 3] == [1, 2, 3] 返回 True(相等性)。

'in' 检查字典中的键还是值?

in 运算符默认检查字典中的。要检查值,请使用 value in dict.values()。要检查键值对,请使用 (key, value) in dict.items()

检查字符串时 'in' 是否区分大小写?

是的,in 运算符在检查字符串时区分大小写。"hello" in "Hello, World!" 返回 False。对于不区分大小写的检查,请将两个字符串转换为相同的大小写:"hello".lower() in "Hello, World!".lower()

检查列表中的 'in' 与集合中的 'in' 在性能上有什么区别?

检查列表中的成员资格具有 O(n) 时间复杂度(线性搜索),而检查集合中的成员资格具有 O(1) 平均时间复杂度(基于哈希的查找)。对于大型集合的频繁成员检查,请使用集合以获得更好的性能。

我可以在自定义类中使用 'in' 吗?

是的,您可以通过实现 __contains__() 方法使自定义类与 in 运算符一起工作。如果您的类是可迭代的(实现 __iter__()),如果未定义 __contains__(),Python 将回退到迭代。

'in' 和 'not in' 有什么区别?

in 运算符如果在集合中找到值则返回 True,而 not in 如果未找到值则返回 Truenot in 等价于 not (value in collection)