Python循环遍历列表并缩短一个

时间:2012-03-29 14:35:38

标签: python list

我有一个清单:

 mylist = ['apple', 'orange', 'dragon', 'panda']

我希望能够遍历列表,对每个元素执行某些操作然后删除元素。我试过这个:

for l in mylist:
    print l
    list.remove(l)

但我的输出是:

apple
dragon

修改

我实际上希望能够在循环中进行一些比较。所以基本上我希望能够逐个取出每个元素,删除列表中的元素,并将其与列表中的所有其他元素进行比较。比较有点复杂,所以我不想使用列表理解。我希望每次减少一个列表,直到列表为空并且所有元素都已相互比较。

获取每个元素,使用它并删除它而不跳过列表中元素的最佳方法是什么?

任何帮助,非常感谢。

REDIT

只是要说清楚 - 真正的要点是遍历每个元素,这是一个字符串片段,并将其与任何一端具有重叠序列的其他片段匹配,从而构建完整的序列。在循环之前,应该从列表中删除正在处理的元素,这样它就不会与它自身进行比较,并且每个处理循环的列表应该缩小1个元素。

如果是更好的列表示例:

mylist = ['apples and or', 'oranges have', 'in common', 'e nothing in c']

给予:

'apples and oranges have nothing in common'

抱歉从一开始就不清楚,但这是我坚持的这个更大问题的一个特定部分。

9 个答案:

答案 0 :(得分:3)

您可以反转列表顺序(如果您想按原始顺序处理项目),然后使用pop()获取项目并依次删除它们:

my_list = ['apple', 'orange', 'dragon', 'panda']
my_list.reverse()
while my_list:
    print(my_list.pop())

答案 1 :(得分:3)

根据您的要求,您希望“能够将每个元素一个接一个地用于列表,并将其与列表中的所有其他元素进行比较”,我相信您是最好的适合使用itertools。在这里,如果没有从列表中删除元素的效率低下,您就可以获得防范,以便将每个组合彼此进行一次比较。由于您的规范似乎没有为删除提供任何用途(除了实现组合的目标),我觉得这很有效。

也就是说,在我看来,列表推导将是解决这个问题的最常见方式,因为它不会影响进行复杂比较的任何能力。

import itertools

l = ['apple', 'orange', 'dragon', 'panda']

def yourfunc(a,b):
    pass

for a, b in itertools.combinations_with_replacement(l, 2):
    yourfunc(a,b)

列表理解方法将改为使用此代码:

[yourfunc(a, b) for a,b in itertools.combinations(l, 2)]

编辑:根据您的其他信息,我相信您应该重新考虑itertools。

import itertools

l =  ['apples and or', 'oranges have', 'in common', 'e nothing in c', 'on, dont you know?']

def find_overlap(a,b):
    for i in xrange(len(a)):
        if a[-i:] == b[0:i]:
            return a + b[i:]
    return ''

def reduce_combinations(fragments):
    matches = []
    for c in itertools.combinations(fragments, 2):
        f = reduce(find_overlap, c[1:], c[0])
        if f: matches.append(f)
    return matches

copy = l
while len(copy) > 1:
    copy = reduce_combinations(copy)

print copy

返回

['apples and oranges have nothing in common, dont you know?']

**编辑:(再次)。 **这种排列是一种实用的解决方案,并且具有额外的好处 - 虽然比上述解决方案有更多的计算,但将提供所有可能的技术匹配。上述解决方案的问题在于它只需要一个答案,这可以通过while循环来证明。因此,它更有效率,但如果存在多个答案,也可能无法返回任何内容。

import itertools

l =  ['apples and or', 'oranges have', 'in common', 'e nothing in c', 'on, dont you know?']

def find_overlap(a,b):
    for i in xrange(len(a)):
        if a[-i:] == b[0:i]:
            return a + b[i:]
    return ''

matches = []
for c in itertools.combinations(l, 2):
    f = reduce(find_overlap, c[1:], c[0])
    if f: matches.append(f)

for c in itertools.combinations(matches, len(matches)):
    f = reduce(find_overlap, c[1:], c[0])
    if f: print f

答案 2 :(得分:1)

有什么理由你不能简单地遍历所有元素,对它们做些什么,然后将列表重置为空列表?类似的东西:

for l in my_list:
   print l
my_list = []
# or, if you want to mutate the actual list object, and not just re-assign
# a blank list to my_list
my_list[:] = []

修改

根据您的更新,您需要做的是使用已提到的弹出方法:

while len(my_list):
   item = my_list.pop()
   do_some_complicated_comparisons(item)

如果您关心订单,那么只需从前面弹出:

my_list.pop(0)

或在循环之前反转列表:

my_list.reverse()

答案 3 :(得分:0)

迭代列表时无法删除元素。处理元素,然后处理列表。所有编程语言都是如此,而不仅仅是Python,因为它会导致这些跳过问题。

作为替代方案,您可以在完成元素后执行list = []

答案 4 :(得分:0)

如果转发顺序无关紧要,我可能会这样做:

l = ['apple', 'orange', 'dragon', 'panda']
while l:
    print l.pop()

鉴于您的编辑,一个很好的选择是使用deque而不是列表。

>>> import collections
>>> l = ['apple', 'orange', 'dragon', 'panda']
>>> d = collections.deque(l)
>>> while d:
    i = d.popleft()
    for j in d:
        if i > j: print (i, j)
... 
('orange', 'dragon')

使用deque很好,因为从任一端弹出是O(1)。最好不要使用deque进行随机访问,因为这比列表慢。

另一方面,由于您每次都在遍历整个列表,因此无论如何,代码的渐近性能将为O(n ** 2)。因此,使用列表并从pop(0)开头弹出是正确的,从渐近的角度来看是合理的(尽管它比使用deque一些常数倍更慢)。

但实际上,由于你的目标似乎是生成组合,你应该考虑hexparrot的答案,这是非常优雅的 - 虽然在性能方面,它不应该与上述基于deque的解决方案完全不同,因为从deque删除项目很便宜。

答案 5 :(得分:0)

制作副本:

for l in original[:]:
  print l
  original.remove(l)

答案 6 :(得分:0)

您可以使用堆栈操作来实现:

while len(mylist):
    myitem = mylist.pop(0)
    # Do something with myitem 
    # ...

答案 7 :(得分:0)

#! C:\python27

import string


list = ['apple', 'orange', 'dragon', 'panda']

print list
myLength = len(list) -1
print myLength
del list[myLength]
print list

[编辑]

继承代码循环并查找用户输入并删除它的单词。

#! C:\python27

import string

whattofind = raw_input("What shall we look for and delete?")
myList = ['apple', 'orange', 'dragon', 'panda']

print myList
for item in myList:
    if whattofind in myList:
        myList.remove(whattofind)
        print myList

答案 8 :(得分:0)

嗯..看到你无法以这种方式删除所有项目,即使你遍历所有这些项目..试试这个:

#! C:\python27

list1 = ["apple","pear","falcon","bear"] #define list 1
list2 = [] #define list 2
item2 ="" #define temp item

for item in list1[:]:
    item2 = item+"2" #take current item from list 2 and do something. (Add 2 in my case)
    list2.append(item2) #add modified item to list2
    list1.remove(item)  #remove the un-needed item from list1

print list1 #becomes empty
print list2 #full and with modified items.

我假设如果你正在进行比较,你可以在''for'之后转储''if''子句以运行比较或其他东西。但这似乎是做到这一点的方式。