2013-02-20 28 views
0

我仍然學習Python中的代碼Python:根據模式創建動態循環

我想根據模式生成一個字符串,我知道的唯一方法就是使用for循環。

在下面的示例代碼中,我創建了一個「vcvcv」模式的循環。 c =輔音,v =元音

如何根據我提供給腳本的模式創建動態循環?

例如。如果pattern爲「cvcvc」,則應該構建循環以生成字符串

幫助指定。

謝謝。

#!/bin/env python 

vowel="aeiou" 
consonant="bcdfghjklmnpqrstvwxyz" 

lvowel=list(vowel) 
lconsonant=list(consonant) 

# pattern for "vcvcv" = ababa 
for a in lvowel: 
    for b in lconsonant: 
    for c in lvowel: 
     for d in lconsonant: 
      for e in lvowel: 
        myname=a+b+c+d+e 
        print myname 

# pattern for "cvcvc" = babab 
# how to make the loop dynamic based on pattern ? 
+0

把它放在一個函數中。字符串也是可迭代的,所以你不需要將它們轉換成列表。 – Volatility 2013-02-20 04:34:21

+0

嘗試遞歸邏輯 – avasal 2013-02-20 04:34:21

回答

5

像這樣的東西應該工作:

import itertools 

mapping = { 
    'v': 'aeiou', 
    'c': 'bcdfghjklmnpqrstvwxyz' 
} 

pattern = 'vcvcv' 

for thing in itertools.product(*map(mapping.get, pattern)): 
    print ''.join(thing) 

這裏的大致工作原理是:

  • map(mapping.get, pattern)只是轉換'vcv'['aeiou', 'bcdfghjklmnpqrstvwxyz', 'aeiou']。它用相應的字符列表替換每個字母。
  • *map(...)解包參數列表。
  • itertools.product()就像一堆嵌套for循環。
  • ''.join(thing)將字符列表連接到單個字符串中。

如果你想這樣做,而不是itertools,你必須做一個遞歸函數。

+0

不錯!小心分享itertools.product的工作原理? – 2013-02-20 04:43:37

+0

@SharuzzamanAhmatRaslan:這是[在文檔中](http://docs.python.org/2/library/itertools.html#itertools.product)。這可能有點難以理解,但寫出自己並不難。這只是一個遞歸函數。 – Blender 2013-02-20 04:44:23

1

如果您剛剛進入編程階段,希望看到比上面列出的itertools更通用的解決方案,那麼遞歸是您最好的選擇,允許您任意嵌套循環。

這裏有一個小小的複雜情況,您可以使用Python generators,或者使用更簡單(但更混亂)的構造。後者的一個例子如下所示。

喜歡的東西

def continuePattern(pat, strSoFar): 
    if pat == '': 
    print strSoFar 
    elif pat[0] == 'v': 
    for c in lvowel: 
     continuePattern(pat[1:], strSoFar + c) 
    elif pat[0] == 'c': 
    for c in lconsonant: 
     continuePattern(pat[1:], strSoFar + c) 

這是幾個可能的實現方式之一,這兩個最樸素的人,我可以想像之一。

0

最初的N個排列一個稍微更復雜,但很容易定製的版本如下,

def gen_pattern(seq, op = ""): 
     vowel="aeiou" 
     consonant="bcdfghjklmnpqrstvwxyz" 

     lvowel=list(vowel) 
     lconsonant=list(consonant) 
     if (not seq): 
      print op 
      return 

     if (seq[0] == 'v'): 
      for v in lvowel: 
        gen_pattern(seq[1:], op+v) 
     elif (seq[0] == 'c'): 
      for c in lconsonant: 
        gen_pattern(seq[1:],op+c) 

if __name__ == "__main__": 
     gen_pattern("vcvcv") 

我同意這是更多的工作,但!