python list.iteritems替换

时间:2014-02-22 11:12:03

标签: python list

我有一个列表,其中一些项目将被移动到一个单独的列表中(通过比较器功能)。这些元素是纯粹的元素。问题是如何迭代这样的列表。

当迭代最简单的方法for element in mylist时,我不知道元素的索引。列表没有.iteritems()方法,这在这里很有用。所以我尝试使用for index in range(len(mylist)):,[1]似乎过于复杂,因为python和[2]不满足我,因为range(len())在开头计算一次,如果我删除一个迭代期间列表中的元素,我将得到IndexError: list index out of range

最后,我的问题是 - 如何迭代python列表,能够从列表中删除元素(使用比较器函数并将它们放在另一个列表中)?

6 个答案:

答案 0 :(得分:2)

您可以使用枚举功能并制作列表的临时副本:

for i, value in enumerate(old_list[:]):
   # i == index
   # value == dictionary
   # you can safely remove from old_list because we are iterating over copy

答案 1 :(得分:1)

我不想触及原始列表并像@ Martol1ni一样,但是一种方法来实现并且不受元素删除的影响将是向后迭代:

for i in reversed(range(len()):
    # do the filtering...

这将仅影响您已经测试/删除的元素的索引

答案 2 :(得分:1)

Haven没试过这个但是......我会给它一个快速的镜头:

new_list = [old.pop(i) for i, x in reversed(list(enumerate(old))) if comparator(x)]

答案 3 :(得分:1)

尝试使用filter命令,如果不需要,也可以使用它覆盖原始列表。

def cmp(i): #Comparator function returning a boolean for a given item
    ...

# mylist is the initial list
mylist = filter(cmp, mylist)

mylist现在是合适物品的发电机。如果您需要多次使用,可以使用list(mylist)

答案 4 :(得分:1)

与从旧项目中删除项目相比,创建新列表确实不是什么大问题。类似地,迭代两次是一个非常小的性能命中,可能被其他因素淹没。除非您有充分的理由不做其他事情,在分析代码的支持下,我建议迭代两次并构建两个新列表:

from itertools import ifilter, ifilterfalse

l1 = list(ifilter(condition, l))
l2 = list(ifilterfalse(condition, l))

如果需要,您可以将其中一个新列表的内容切片 - 分配到原始列表中:

l[:] = l1

如果您完全确定需要1-pass解决方案,而且您绝对确定要修改原始列表而不是创建副本,则以下内容可避免pop的二次性能命中从列表中间ping:

j = 0
l2 = []
for i in range(len(l)):
    if condition(l[i]):
        l[j] = l[i]
        j += 1
    else:
        l2.append(l[i])
del l[j:]

我们将列表中的每个元素直接移动到其最终位置,而不会浪费不需要移位的时移元素。如果需要,我们可以使用for item in l,它可能会更快一点,但是当算法涉及修改我们正在迭代的事物时,我更喜欢显式索引。

答案 5 :(得分:0)

你可以做到这一点,虽然可能只有一行。

new_list1 = [x for x in old_list if your_comparator(x)]
new_list2 = [x for x in old_list if x not in new_list1]
相关问题