在 Python 中迭代时从列表中删除特定索引
Remove a specific index from a list while iterating in Python
我通过以下方式学习了如何从 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
您可以使用列表理解生成相同的东西:
somelist = [i for idx, i in enumerate(lists) if i[0] != lists[idx][0]]
根据任何文档,基本上不支持您的尝试。通常,除非文档明确说明可以,否则您不应在迭代时修改容器。如果它 "seems to work" 没有帮助,因为您只是利用了您正在使用的实现版本中的某些行为,但该行为可能会更改,恕不另行通知(破坏您的程序)。
您需要做的是将修改与迭代分开。使用列表理解是实现此目的的一种方法,但基本上你在做同样的事情。
有几个变体,您可以复制数据并遍历它并修改原始数据。或者您在迭代原件之前制作副本并修改副本,然后更新原件。还有一种变体,您可以在迭代期间构建副本,然后更新原始版本。
此外,您的示例存在缺陷,因为您没有考虑到修改会影响修改后 list
中的正确索引。例如,如果您有列表 [1, 1, 2, 2, 3, 3]
,那么当您删除重复项 1
s 和 2
s 并检测到重复项 3
s 时,您就有了列表 [1, 2, 3, 3]
,但是当您找到重复的 3
s 时,您会在索引 4
和 5
处找到它们,但删除后它们位于索引 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
修改副本的方案基本相同,迭代构建副本的方案略有不同
lists = list() # a list of lists
tmp = []
for idx, line in 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:
tmp.append(line)
else:
tmp.append( line )
lists[:] = tmp
最后一行是原点更新的地方,否则循环通过将那些要保留的元素附加到 tmp
(而不是复制所有元素然后删除那些不保留的元素)来工作。
我通过以下方式学习了如何从 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
您可以使用列表理解生成相同的东西:
somelist = [i for idx, i in enumerate(lists) if i[0] != lists[idx][0]]
根据任何文档,基本上不支持您的尝试。通常,除非文档明确说明可以,否则您不应在迭代时修改容器。如果它 "seems to work" 没有帮助,因为您只是利用了您正在使用的实现版本中的某些行为,但该行为可能会更改,恕不另行通知(破坏您的程序)。
您需要做的是将修改与迭代分开。使用列表理解是实现此目的的一种方法,但基本上你在做同样的事情。
有几个变体,您可以复制数据并遍历它并修改原始数据。或者您在迭代原件之前制作副本并修改副本,然后更新原件。还有一种变体,您可以在迭代期间构建副本,然后更新原始版本。
此外,您的示例存在缺陷,因为您没有考虑到修改会影响修改后 list
中的正确索引。例如,如果您有列表 [1, 1, 2, 2, 3, 3]
,那么当您删除重复项 1
s 和 2
s 并检测到重复项 3
s 时,您就有了列表 [1, 2, 3, 3]
,但是当您找到重复的 3
s 时,您会在索引 4
和 5
处找到它们,但删除后它们位于索引 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
修改副本的方案基本相同,迭代构建副本的方案略有不同
lists = list() # a list of lists
tmp = []
for idx, line in 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:
tmp.append(line)
else:
tmp.append( line )
lists[:] = tmp
最后一行是原点更新的地方,否则循环通过将那些要保留的元素附加到 tmp
(而不是复制所有元素然后删除那些不保留的元素)来工作。