Skip to main content
 首页 » 编程设计

python之遍历列表并删除 Python 中的条目

2025年05月04日36kuangbin

我想在 Python 中遍历列表并删除特定项目。 我不想制作一个新的接受项目列表,因为在我的完整示例中,我想对我的列表进行一系列改进。这是一个简单的示例,我尝试删除列表中所有小于 3 的数字。

example = [1.,2.,3.,4.,5.,6.] 
for e in example: 
  if e < 3.: 
    print "Removing:", e 
    example.remove(e) 
  else: 
    print "Accepting:", e 
print "NAIVE:", example  
 
Removing: 1.0 
Accepting: 3.0 
Accepting: 4.0 
Accepting: 5.0 
Accepting: 6.0 
NAIVE: [2.0, 3.0, 4.0, 5.0, 6.0] 

它失败了。我认为它失败了,因为删除列表中的项目会混淆 for 循环正在运行的索引,即一旦项目 1. 被删除,项目 2. 在列表中的位置 0,但到那时,循环在位置 1。

我可以用 deepcopy 解决这个问题,如下所示:

example = [1.,2.,3.,4.,5.,6.] 
import copy 
for e in copy.deepcopy(example): 
  if e < 3.: 
    print "Removing:", e 
    example.remove(e) 
  else: 
    print "Accepting:", e 
print "DEEPCOPY:",  example 
 
Removing: 1.0 
Removing: 2.0 
Accepting: 3.0 
Accepting: 4.0 
Accepting: 5.0 
Accepting: 6.0 
DEEPCOPY: [3.0, 4.0, 5.0, 6.0] 

这在这里行得通,但这是好的做法吗?会不会导致其他意想不到的bug?有没有更好的方法来实现这一目标?或者这种结构(循环并从列表中删除)从根本上来说是不合理的?

我不想制作一个新的已接受项目列表,因为我想将一系列标准逐一应用于我的列表,并相应地删除项目。我不想为我应用的每个标准(可能有很多)创建一个新列表,我也不想一次应用我的所有标准(因为这有助于查看每个标准删除了多少项目等) .

请您参考如下方法:

我不明白你为什么不只用你想保留的项目构建一个新列表,因为你似乎并不关心构建一个新列表(毕竟,这就是 copy 确实如此)。

所以我会做

example = [f for f in example if f >= 3] 

如果您确实想遍历列表并更改它,也许遍历索引并向后移动:

for i in range(len(example) - 1, -1, -1): 
    if example[i] < 3: 
        del example[i] 

但这有点特别,除非真的有必要,否则我会避免它。

为了表明您不需要愚蠢的 example_1、example_2、old_example 等变量,请考虑:

# Here is a number of tests for things we want throw out 
def some_really_complicated_test_on_a_number(f): 
    ... put any kind of code here and return True if we want to 
    delete the number... 
 
TESTS = ( 
    lambda f: f < 3, 
    lambda f: f > 16, 
    lambda f: (int(f) % 2) == 1,  # Integer is odd 
    some_really_complicated_test_on_a_number, 
    # etc 
) 

这是一个接受列表和测试的函数,打印带有“接受”和“拒绝”的项目,并返回一个包含剩余项目的新列表:

def filter_with_prints(l, test): 
    result = [] 
    for f in l: 
         if test(f): 
             print("Rejecting: {}".format(f)) 
         else: 
             result.append(f) 
             print("Accepting: {}".format(f)) 
    return result 

我们可以像这样调用很多测试:

example = [1., 2., 3., 4., 5., 6.] 
 
for test in TESTS: 
    example = filter_with_prints(example, test)