我正在尝试在python中生成morris序列.我目前的解决方案如下,但我觉得我只是在python中写了c.任何人都可以提供更多的pythonic解决方案吗?
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)]
nosklo.. 24
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数字等.
然后显然不需要将列表中的先前morris数的整个列表存储,因为递归仅在n := f(n-1)
任何时候.
最后,使用itertools给它一个功能性触摸总是值得一两个极客;)我将生成器表达式分成几行,使它更容易在眼睛上.
这个解决方案中的主要丑陋来自于len()
无法在迭代器上调用的事实,并为我们提供了一个需要str的int.另一个hickup是嵌套的str.join),将整个东西再次压平成str.
如果要从任意数字开始序列,请定义如下函数:
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
希望你喜欢!
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
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数字等.
然后显然不需要将列表中的先前morris数的整个列表存储,因为递归仅在n := f(n-1)
任何时候.
最后,使用itertools给它一个功能性触摸总是值得一两个极客;)我将生成器表达式分成几行,使它更容易在眼睛上.
这个解决方案中的主要丑陋来自于len()
无法在迭代器上调用的事实,并为我们提供了一个需要str的int.另一个hickup是嵌套的str.join),将整个东西再次压平成str.
如果要从任意数字开始序列,请定义如下函数:
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
希望你喜欢!