python look-and-say序列改进了

时间:2011-08-07 12:23:30

标签: python sequences

我想首先介绍一下看起来顺序。它就像a = {1, 11, 21, 1211, 111221 ...

系统检查前一个数字并计算数字。

1 = one 1 (so = 11)
11 = two 1 (so = 21)
21 = one 2 one 1 (so = 1211)

作为序列的规则,没有数字可以超过3,所以创建一个转换表可以适应。但它不是语义,我不喜欢它。

我想要的是一个脚本,它会评估给定的值并返回一个看似相似的字符串。

但是,为了超越限制,我希望它甚至可以评估字符,因此它可以返回1A2b41

我一直试图让它工作几个小时,逻辑变得糟糕,我现在正处于脑力激荡状态。

这是实际不起作用的脚本(返回false结果),但至少可以给你这个想法。

def seq(a):
    k,last,result,a = 1,'','',str(a)
    for i in range(len(a)):
        if last==a[i]:k+=1
        else:
            result = result+str(k)+a[i]
            k=1
        last = a[i]
    return result

3 个答案:

答案 0 :(得分:14)

您可以使用groupby,这正是您想要的:

from itertools import groupby
def lookandsay(n):
    return ''.join( str(len(list(g))) + k for k, g in groupby(n))

>>> lookandsay('1')
'11'
>>> lookandsay('1A2b41')
'111A121b1411'
>>> lookandsay(lookandsay('1A2b41'))
'311A1112111b111421'

groupby从可迭代对象返回连续的键和组。键是为每个元素计算的函数,或者如果未指定则为标识函数(如上所述)。该组是一个迭代器 - 当键函数的值发生变化时,会生成一个新组。因此,例如,根据文档:

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D

答案 1 :(得分:4)

我认为你被困的部分原因是你使用了无意义的变量名。你很好地描述了这个问题并按名称调用了它,但是甚至没有为你的函数使用该名称。

如果你认为你开始的字符串为“look”,而你最后的字符串为“say”,那就是一个开始。 result可能还不错,但ak让您感到困惑。我认为last具有误导性,因为它可能意味着先前或最终。

此外,Python的for实际上是foreach的原因 - 你每次都在“看”一个字符中,所以在循环中明确地这样做。

def looksay(look):
    look = str(look)
    prev, count, say = look[0], 1, ''
    for char in look[1:]:
        if char == prev:
            count += 1
            continue
        say += str(count) + prev
        prev = char
        count = 1
    return say + str(count) + prev

间距不太重要,但Python确实有standard coding style,它确实有助于使用它。解析代码所花费的心理时间越少,对问题的关注就越多。

答案 2 :(得分:3)

我可以看到您的代码存在两个问题:

  • 虽然计数器result不计算字符k,但计时器a[i] ka[i]展开lasta[i]展开。在此last替换result = result+str(k)+last(您可能不希望在第一轮中添加任何内容)。

  • 在循环之后,你必须再次添加计数器的最后一个值和最后一个字符(这还没有完成),即在循环后添加另一个def seq(a): a = str(a) k,last,result = 1,a[0],'' for i in range(1,len(a)): if last==a[i]:k+=1 else: result = result+str(k)+last k=1 last = a[i] result = result+str(k)+last return result

    < / LI>

总的来说看起来像是

{{1}}