最直接安全的过滤None方式是[x for x in my_list if x is not None],它只剔除None而不影响0、False等falsy值,避免常见错误[x for x in my_list if x]导致的数据误删。

用列表推导式过滤 None 最直接的方式
直接写 [x for x in my_list if x is not None] 就行,这是最安全、最明确的写法。它只剔除真正为 None 的元素,不会误删 0、False、空字符串 '' 或空列表 [] 这类“falsy 但非 None”的值。
常见错误是写成 [x for x in my_list if x]——这会把 0、False 等一并干掉,尤其在处理数值或布尔数据时容易出 bug。
- 推荐始终用
is not None,而不是!= None(虽然后者通常也生效,但is是语义正确且更快的判断方式) - 如果原列表嵌套了对象(比如字典或自定义类),且某些元素可能为
None,这个写法依然可靠 - 性能上几乎没有损耗,Python 对
is判断做了高度优化
当列表里混着 NaN 和 None 时怎么办
如果你的数据来自 pandas 或 NumPy(比如读 CSV 后的列),很可能同时存在 None 和 float('nan')。此时 x is not None 无法过滤 NaN,因为 NaN is not None 为 True,但 NaN == NaN 是 False,常规判断会失效。
这时得结合 pandas.notna() 或 math.isnan():
立即学习“Python免费学习笔记(深入)”;
import math [x for x in my_list if x is not None and (not isinstance(x, float) or not math.isnan(x))]
更简洁的做法是先统一转成 pandas Series 再处理:pd.Series(my_list).dropna().tolist(),它默认同时清除 None 和 NaN。
想原地修改列表?别用列表推导式
列表推导式总是生成新列表,不会修改原列表。如果你明确需要就地过滤(比如因内存限制不能新建大列表),就得用 list.remove() 或反向遍历 + del:
- 错误示范:
for x in my_list: if x is None: my_list.remove(x)——边遍历边删会导致跳过下一个元素 - 正确做法(反向索引):
for i in range(len(my_list) - 1, -1, -1): if my_list[i] is None: del my_list[i] - 或者更稳妥:用
while None in my_list: my_list.remove(None),但注意这在大量None时效率低
为什么不用 filter()?
list(filter(lambda x: x is not None, my_list)) 功能等价,但可读性差一点,且 Python 3 中 filter() 返回迭代器,不显式转 list 容易踩坑。另外,lambda 在这里没带来任何优势,纯属多套一层。
除非你已经在用函数式风格封装逻辑(比如传入可配置的判别函数),否则没必要绕路。列表推导式在这里就是最自然的选择。
真正容易被忽略的是:如果列表里有自定义类实例,且该类重载了 __eq__ 或 __bool__,is not None 依然安全,而基于值的判断可能意外失效。


















