我想首先介绍一下看起来顺序。它就像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
答案 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
可能还不错,但a
和k
让您感到困惑。我认为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]
k
,a[i]
展开last
和a[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
。
总的来说看起来像是
{{1}}