Skip to main content
 首页 » 编程设计

python之从列表中删除某些重复元素的最佳(Pythonic)方法是什么

2025年05月04日20落叶无声

考虑以下示例:

In [1]: lst = list(range(10)) * 2 
 
In [2]: lst 
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
 
In [3]: for i, x in enumerate(list(lst)): 
   ...:     if i > 10 and x % 2: 
   ...:         lst.remove(x) 
   ...:          
 
In [4]: lst 
Out[4]: [0, 2, 4, 6, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

所以这个策略不起作用,因为它删除了 list 中第一次出现的项目,这不是我想要的。

In [5]: lst = list(range(10)) * 2 
 
In [6]: for i, x in enumerate(list(lst)): 
   ...:     if i > 10 and x % 2: 
   ...:         del lst[i] 
   ...:          
--------------------------------------------------------------------------- 
IndexError                                Traceback (most recent call last) 
<ipython-input-6-bbec803a1844> in <module>() 
      1 for i, x in enumerate(list(lst)): 
      2     if i > 10 and x % 2: 
----> 3         del lst[i] 
      4  
 
IndexError: list assignment index out of range 

我的其他策略也不起作用,因为初始 list 的副本最终具有更大的索引,因为原始 list 不断从中删除项目。

以下确实有效:

In [7]: lst = list(range(10)) * 2 
 
In [8]: idx = 0 
 
In [9]: for i, x in enumerate(list(lst)): 
   ...:     if i > 10 and x % 2: 
   ...:         lst.pop(i-idx) 
   ...:         idx += 1 
   ...:          
 
In [10]: lst 
Out[10]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8] 

还有这个:

In [11]: lst = list(range(10)) * 2 
 
In [12]: idx = 0 
 
In [13]: for i, li in enumerate(x for x in lst.copy()): 
    ...:     if i > 10 and li % 2: 
    ...:         lst.pop(i-idx) 
    ...:         idx += 1 
    ...:          
 
In [14]: lst 
Out[14]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8] 

有哪一种工作方法比另一种更好吗?有没有更好的方法来实现我想要的?如果我在 if 测试中有 or 语句怎么办?

In [15]: lst = list(range(10)) * 2 
 
In [16]: idx = 0 
 
In [17]: for i, x in enumerate(list(lst)): 
    ...:     if i > 10 and (x % 2 or x // 5): 
    ...:         lst.pop(i-idx) 
    ...:         idx += 1 
    ...: 
 
In [18]: lst 
Out[18]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4] 

请您参考如下方法:

每当您发现自己正在编写一个 for 循环来构造或修改一个列表时,请问问自己如何使用列表理解来完成它。列表理解是 Pythonic 的。

>>> [x for i, x in enumerate(lst) if i <= 10 or x % 2 == 0] 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8]