2009-02-16 23 views
5

我试图产生蟒morris sequence。我目前的解决方案如下,但我觉得我只是在python中写入c。任何人都可以提供更pythonic解决方案?任何人都可以提供生成莫里斯序列的更Python的方式?

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

这听起来像哟你在问鱼拍舞蹈。结合巨蟒和莫里斯舞... :-) – 2009-02-16 16:29:32

+0

如果这件事情并不需要至少10个字符我会一直只是回应道:d – 2009-02-16 16:30:39

回答

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 
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)) 

首先我会做迭代无限,让消费者决定,他的量有多大希望。这样他就可以得到每一个比x短的莫里斯数字或者第一个x数字等。

然后显然没有必要把以前morris数字的整个列表存储在一个列表中,因为递归只是无论如何,它们都是n := f(n-1)

最后,使用itertools给它的功能的触摸总是值得一极客点或两个;)我分裂发生器表达成几行,以使在眼睛上它更容易一些。

这个解决方案的主要丑陋来自于这样一个事实,即len()不能在迭代器上调用,并给我们一个int,我们需要一个str。另hickup是嵌套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 

希望你喜欢它!

相关问题