2015-12-07 48 views
0

我試圖遍歷長度1到8(含)之間的所有可能的組合string我的主要目標是讓代碼儘可能少。要做到這一點,我目前使用Python的itertools庫:Python 2.7:迭代一行代碼中的字符串的所有組合

import itertools, string 
for i in xrange(1, 9): 
    for x in itertools.imap(''.join, itertools.product(string.letters + string.digits + string.punctuation, repeat = i)): 
     if x == some_string: 
      # do something, like print x 
      print x 
      break 
    else: 
     continue 
    break 

我希望能夠做迭代在同一行,這樣我就可以break了一次內外for迴路,和將不需要的else:continuebreak等事情是這樣的:(使用嵌套循環for

for x in (itertools.imap(''.join, itertools.product(string.letters + string.digits + string.punctuation, repeat = i)) for i in xrange(1, 9)): 
    if x == some_string: 
     print x 
     break 

然而,x原來是一個<itertools.imap object>。於是,我就遍歷x,使用多個嵌套循環for(因爲如果我使用內循環for,我將不得不break多次再次):

for y in (x for x in (itertools.imap(''.join, itertools.product(string.letters + string.digits + string.punctuation, repeat = i)) for i in xrange(1, 9))): 
    if y == some_string: 
     print y 
     break 

不幸的是,仍然無法正常工作; y不知何故仍然是<itertools.imap object>。我是一名自學Python程序員,generatorsiterables等有時令我感到困惑。有人可以幫我把迭代到一行嗎?非常感謝。

+3

遍歷所有這些組合是一個**可怕,可怕的**,以檢查是否some_string''就是其中的一種方式。 – user2357112

+0

我同意;然而,蠻力是我得到的任務。 –

+1

這樣......你會有'Memory Error', –

回答

2

您是非常接近的,你需要itertools.chain爲「contatenate」幾個迭代器,如:

alphabet = "ab" 

for x in itertools.imap(''.join, itertools.chain(
      *(itertools.product(alphabet, repeat=i) 
      for i in range(1,9)))): 
    print x 

請注意,鏈接參數列表,所以我使用可變參數與生成器表達式。

編輯:使用itertools.chain.from_iterable從評論:

from itertools import chain, imap, product 

alphabet = "ab" 

for x in imap(''.join, chain.from_iterable(product(alphabet, repeat=i) 
          for i in range(1,9))): 
    print x 
+0

謝謝,這解決了我的問題! –

+1

還有'chain.from_iterable',當輸入迭代器的數量是無限的時候,它是特別有用的。 – user2357112

0

如果你想打破了多個循環,你可以用它代替「破發」,「回報」

+0

這張貼作爲評論未回覆,因爲它沒有回覆OP要求... –

+0

我無法評論,因爲我需要50點聲望才能這樣做。我只能評論我自己的問題和答案,但你是對的! – dima