在生成莫里斯序列方面,谁能提供更加Python风格的方法?

2024-06-17 07:55:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用python生成morris sequence。我当前的解决方案如下,但我觉得我只是用python编写了c。有人能提供一个更像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)]

Tags: andinforlenifdefcountrange
2条回答
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的每个morris数或前x个数,等等

然后显然不需要将以前morris数字的整个列表存储在一个列表中,因为不管怎样递归都只是n := f(n-1)。在

最后,使用itertools给它一个功能性的触感总是值得一两个极客的点;)我把生成器表达式分成几行,使它看起来更简单一些。在

这个解决方案的主要缺点是不能在迭代器上调用len(),并在需要str的地方给我们一个int。另一个问题是嵌套的结构连接)再把整件事弄平。在

如果要从任意数字开始序列,请定义如下函数:

^{pr2}$

如果你想打开发电机,你可以这样写:

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

希望你喜欢!在

^{}似乎非常适合!只需定义一个next_morris函数,如下所示:

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

就这些!!!看:

^{pr2}$

我可以用它做发电机:

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

相关问题 更多 >