Python中Series的in关键字在if与for循环中行为差异原因是什么
pandas Series中
in关键字的行为差异原因 底层实现逻辑
Python中in关键字的两种使用场景,分别对应目标对象的两个不同特殊方法:
- 布尔判断场景(
if x in obj):调用对象的__contains__方法返回布尔值 - 迭代遍历场景(
for x in obj):调用对象的__iter__方法返回迭代器
pandas的Series对这两个方法的实现做了差异化设计,直接导致了两种场景下的行为不同:
Series.__contains__方法:默认检查目标是否存在于Series的索引中
对应示例代码:
这里判断的就是var = 1 if var in m: print(var*20)1是否在m的索引[1,2...12]中,符合条件所以输出20。如果要判断值是否存在,需要显式写x in m.values。Series.__iter__方法:默认遍历Series的值
对应示例代码:
这里迭代的就是m的取值for var in m: print(var)['jan','feb'...'dec'],所以会输出所有月份名称。如果要遍历索引,可以显式调用for idx in m.index,同时遍历索引和值可以用for idx, val in m.items()。
设计逻辑依据
这个设计并非矛盾,而是pandas团队针对两类场景的高频使用需求做的优化:
- 布尔判断场景下,用户使用
x in series的需求大多是判断指定标签(索引)是否存在,比如校验某条数据的主键是否在Series中,这个场景的出现频率远高于判断某个值是否存在,所以把__contains__的默认实现绑定到索引。 - 迭代场景下,Series作为兼容NumPy数组的一维数据结构,要和NumPy数组的迭代行为对齐(NumPy数组迭代默认遍历元素值),而且用户迭代Series时大多需要处理元素值而非索引,所以把
__iter__的默认实现绑定到值。
如果要避免歧义,建议所有场景都显式指定操作的是索引还是值:比如判断索引用x in m.index,迭代值用for v in m.values,代码可读性会更高。
内容的提问来源于stack exchange,提问作者tjt
相关产品推荐
相关产品推荐

