我了解如何在从here迭代时从列表中删除项目:
somelist = [x for x in somelist if determine(x)]
此外,如何在迭代时从列表中删除特定索引?例如,
lists = list() # a list of lists
for idx, line in enumerate(lists):
if idx > 0:
cur_val = line[0] # value of current line
prev_val = lists[idx-1][0] # value of previous line
if prev_val == cur_val :
del lists[idex-1] # IndexError: list index out of range
答案 0 :(得分:1)
基本上,根据任何文档都不支持您的尝试。通常,您不应在迭代时修改容器,除非文档明确说明您可以。如果它似乎能够起作用,它就无济于事。因为您只是利用了您正在使用的实现版本中的某些行为,但该行为可能会在未事先通知的情况下发生变化(破坏您的程序)。
您需要做的是将修改与迭代分开。使用列表理解是实现这一目标的一种方法,但基本上你是在做同样的事情。
有一些变体,要么你复制数据并重复数据并修改原始数据。或者在复制原件之前复制并修改副本然后更新原件。还有在迭代过程中构建副本然后更新原始副本的变体。
此外,您的示例存在缺陷,因为您没有考虑到修改会影响修改后的list
中的正确索引。例如,如果您有列表[1, 1, 2, 2, 3, 3]
,那么当您删除重复项1
和2
并检测到重复的3
时,您就会拥有列表{ {1}},但是当您找到重复的[1, 2, 3, 3]
时,您会在索引3
和4
找到这些内容,但在删除后,它们位于索引5
和{{ 1}}而不是。
2
您修改副本的解决方案基本相同,但在迭代期间构建副本的解决方案略有不同。
3
最后一行是更新原点的位置,否则循环的工作方式是将要保留的那些元素附加到lists = list() # a list of lists
cur = 0 # index in the modified list
for idx, line in list(enumerate(lists)): # make a copy of the original
if idx > 0:
cur_val = line[0] # value of current line
prev_val = lists[idx-1][0] # value of previous line
if prev_val == cur_val:
del lists[cur-1] # IndexError: list index out of range
else:
cur += 1
else:
cur += 1
(而不是复制所有元素,然后删除那些不被保留的元素) )。
答案 1 :(得分:0)
您可以使用列表解析生成相同的内容:
somelist = [i for idx, i in enumerate(lists) if i[0] != lists[idx][0]]