2012-05-12 13 views
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" 

我可以開始我的循環與當前外循環的迭代器。如何以不使用切片的更加pythonic的方式做到這一點?

這裏是我所想的更Python的方式爲例:

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"    
+2

等待...你又在做什麼? – Makoto

+0

你會編輯你的原始文章,並詳細說明你正在努力完成什麼?謝謝。 – octopusgrabbus

+0

在內循環中,我想從外循環的迭代器開始,例如,當我在外循環中的第3項時我也想用內循環中的第3項開始。 – varantir

回答

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 
+0

以及即時通訊不是真的滿足,但我想沒有更好的解決方案 – varantir

+0

@varantir:看到更新... – georg

+0

這真棒。感謝thg435,這是一個很好的實現。 – varantir

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 
+0

因此,問題在於你不能在兩者之間進行操作,例如,如果你想在k2上有一些條件,而不是在k1上。 – varantir

+0

的確如此,但如果您願意的話,您可以將它與'itertools.groupby'結合使用。我會編輯以表明這一點。 (雖然這有點愚蠢。) – Dougal

+0

但那根本不靈活。正如thg435指出的那樣,我想「保存」發電機狀態。 – varantir

0
l = [...] 
for i, k1 in enumerate(l): 
    for i, k2 in enumerate(l[i:]): 
     # this loop skippes the elements after k1 
     ... 
+0

切片是昂貴的。 (...不使用切片) – varantir