2

我想在几个循环中循环一个列表,总是从最后一个循环的项目开始:

import itertools as it
list1=[1,2,3,4,5,6,7,8]
a=iter(list1)
while a.next()!= 8:
    a,b=it.tee(a) #copy the iterator
    while b.next()!=8:
        b,c=it.tee(b)
        while c.next()!=8:
            print "yaaay"

在这段代码中,我可以使用外循环的当前迭代器开始我的循环。如何在不使用 slice 的情况下以更 Pythonic 的方式执行此操作?

这是我正在考虑的更pythonic方式的示例:

list1=[1,2,3,4,5,6,7,8]
a=iter(list1)
for k1 in list1:
    for k2=k1 in list1:
        for k3=k2 in list1:
            print "yaaay"            
4

3 回答 3

2

据我了解,您正在寻找在某个时候“保存”生成器状态然后“恢复”它的方法。使用tee是正确的想法,PEP 0323对此有更多信息。

import itertools

lst = range(10)
it = iter(lst)

while True:
    print it.next(), '>>',
    it, saved = itertools.tee(it)
    for subitem in it:
        print subitem,
    it = saved
    print

更新:

import itertools

class fancy_it(object):
    stack = []

    def __init__(self, iterable=None):
        if not iterable:
            prev = fancy_it.stack[-1]
            prev.it, iterable = itertools.tee(prev.it)
        self.it = iter(iterable)

    def __iter__(self):
        fancy_it.stack.append(self)
        try:
            while True:
                yield self.it.next()
        except StopIteration:
            fancy_it.stack.pop()
            raise StopIteration


for x in fancy_it(range(10)):
    print x
    for y in fancy_it():
        print '**', y
        for z in fancy_it():
            print '****', z
于 2012-05-12T20:04:50.793 回答
2

您可以尝试itertools.combinations_with_replacement,它将在同一组元素上循环,但在单个 for 循环中而不是三个:

import itertools
list1 = [1,2,3,4,5,6,7,8]
for k1, k2, k3 in itertools.combinations_with_replacement(list1, 3):
     print k1, k2, k3

要将其再次转换为相当于三个 for 循环,您可以itertools.groupby像这样使用:

import itertools
import operator

list1 = [1,2,3,4,5]
combos = itertools.combinations_with_replacement(list1, 3)

for k1, k1_groups in itertools.groupby(combos, operator.itemgetter(0)):
    for k2, k2_groups in itertools.groupby(k1_groups, operator.itemgetter(1)):
        print k1, k2, '==>',
        for _, _, k3 in k2_groups:
            print k3,
        print

这打印出来

1 1 ==> 1 2 3 4 5
1 2 ==> 2 3 4 5
1 3 ==> 3 4 5
1 4 ==> 4 5
1 5 ==> 5
2 2 ==> 2 3 4 5
2 3 ==> 3 4 5
2 4 ==> 4 5
2 5 ==> 5
3 3 ==> 3 4 5
3 4 ==> 4 5
3 5 ==> 5
4 4 ==> 4 5
4 5 ==> 5
5 5 ==> 5
于 2012-05-12T20:05:04.940 回答
0
l = [...]
for i, k1 in enumerate(l):
    for i, k2 in enumerate(l[i:]):
        # this loop skippes the elements after k1
        ...
于 2012-05-12T20:07:13.920 回答