2009-02-16 16 views
5

मैं अजगर में morris sequence उत्पन्न करने की कोशिश कर रहा हूं। मेरा वर्तमान समाधान नीचे है, लेकिन मुझे लगता है कि मैंने अभी पायथन में सी लिखा है। क्या कोई और अधिक पायथनिक समाधान प्रदान कर सकता है?कोई भी मॉरिस अनुक्रम उत्पन्न करने का एक और पाइथोनिक तरीका प्रदान कर सकता है?

def morris(x): 
    a = ['1', '11'] 
    yield a[0] 
    yield a[1] 
    while len(a) <= x: 
     s = '' 
     count = 1 
     al = a[-1] 
     for i in range(0,len(al)): 
      if i+1 < len(al) and al[i] == al[i+1]: 
       count += 1 
      else: 
       s += '%s%s' % (count, al[i]) 
       count = 1 
     a.append(s) 
     yield s 
a = [i for i in morris(30)] 
+0

यह यो की तरह लगता है आप मछली slapping नृत्य के बारे में पूछ रहे हैं। यह मॉन्टी पायथन और मॉरिस नृत्य को जोड़ता है ... :-) –

+0

यदि इस चीज़ को कम से कम 10 वर्णों की आवश्यकता नहीं थी तो मैंने अभी जवाब दिया होगा: डी –

+0

आप दोनों को उपज() आईएनजी और मूल्यों को संग्रहीत क्यों कर रहे हैं [] ? – Javier

उत्तर

23

itertools.groupby पूरी तरह से फिट लगता है! इस प्रकार बस एक next_morris समारोह को परिभाषित:

def next_morris(number): 
    return ''.join('%s%s' % (len(list(group)), digit) 
        for digit, group in itertools.groupby(str(number))) 

सब है कि !!! देखो:

print next_morris(1) 
11 
print next_morris(111221) 
312211 

मैं इस्तेमाल कर सकते हैं कि एक जनरेटर बनाने के लिए:

def morris_generator(maxlen, start=1): 
    num = str(start) 
    while len(num) < maxlen: 
     yield int(num) 
     num = next_morris(num) 

उपयोग:

for n in morris_generator(10): 
    print n 

परिणाम:

1 
11 
21 
1211 
111221 
312211 
13112221 
+0

आपको बहुत धन्यवाद। मैं वास्तव में, वास्तव में iterools पुस्तकालय बेहतर सीखने की जरूरत है –

6
from itertools import groupby, islice 

def morris(): 
    morris = '1' 
    yield morris 
    while True: 
     morris = groupby(morris) 
     morris = ((len(list(group)), key) for key, group in morris) 
     morris = ((str(l), k) for l, k in morris) 
     morris = ''.join(''.join(t) for t in morris) 
     yield morris 

print list(islice(morris(), 10)) 

सबसे पहले मैं iterator अनंत बनाने के लिए और उपभोक्ता निर्णय लेते हैं, इसके बारे में वह कितना चाहता है चाहते हैं। इस तरह वह या तो x या पहले x संख्याओं से कम प्रत्येक मॉरिस नंबर प्राप्त कर सकता है,

फिर रिकॉर्शन केवल एक सूची में पिछले मॉरिस संख्याओं की पूरी सूची को स्टोर करने की आवश्यकता नहीं है, क्योंकि रिकर्सन केवल वैसे भी n := f(n-1)

आखिरकार, इसे एक कार्यात्मक स्पर्श देने के लिए itertools का उपयोग करना हमेशा एक गीक बिंदु या दो के लायक होता है;) मैंने जेनरेटर अभिव्यक्ति को कई रेखाओं में विभाजित किया ताकि यह आंखों पर थोड़ा आसान हो सके।

इस समाधान में मुख्य कुरूपता इस तथ्य से आती है कि len() एक पुनरावर्तक पर नहीं बुलाया जा सकता है और हमें एक int प्रदान करता है जहां हमें एक str की आवश्यकता होती है। दूसरी हिकअप नेस्टेड str.join है) पूरी चीज को एक स्ट्र में फिर से भरने के लिए।

आप, मनमाने ढंग से संख्या से अनुक्रम शुरू इस तरह समारोह निर्धारित करना चाहते हैं:

def morris(morris=None): 
    if morris is None: 
     morris = '1' 
[...] 

आपको लगता है कि जनरेटर घूम चाहते हैं, आप इसे इस प्रकार लिख सकते हैं:

def morris(): 
    morris = '1' 
    yield morris 
    while True: 
     print morris 
     morris = ''.join(''.join(t) 
        for t in ((str(len(list(group))), key) 
         for key, group in groupby(morris))) 
     yield morris 

मुझे यकीन नहीं है कि मुझे दो कार्यों में विभाजित करना पसंद है, लेकिन यह सबसे अधिक पढ़ने योग्य समाधान प्रतीत होता है:

def m_groupby(s): 
    for key, group in groupby(s): 
     yield str(len(list(group))) 
     yield key 

def morris(): 
    morris = '1' 
    yield morris 
    while True: 
     morris = ''.join(m_groupby(morris)) 
     yield morris 

आशा है कि आप इसे पसंद करेंगे!

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^