>>> import itertools
>>> s = 'd13fx4e2'
>>> [''.join(group) for (key, group) in itertools.groupby(s, str.isdigit)]
['d', '13', 'ff', '4', 'e', '2']
现在,我们用mshsayem压缩字符的方式压缩它:
^{pr2}$
所以:
def expand(s):
groups = (''.join(group) for (key, group) in itertools.groupby(s, str.isdigit))
return ''.join(c*int(d) for (c, d) in zip(groups, groups))
让我们看看如何手动完成这项工作,只使用新手能够理解的工具。实际上学习
zip
和迭代器和理解等等都是比较好的,但也可能有助于了解你写同样东西的笨拙和冗长。在那么,让我们从单个字符和个位数开始:
这是一个非常简单的状态机。有两种状态:要么下一个字符是要重复的字符,要么是一个给出重复计数的数字。在阅读了前者之后,我们还没有什么要补充的(我们知道这个角色,但不知道要重复多少次),所以我们只需要切换状态。在阅读了后者之后,我们现在知道要添加什么(因为我们既知道字符又知道重复计数),所以我们这样做了,还切换了状态。就这些了。在
现在,要将其扩展到多字符重复字符串和多位数重复计数:
^{pr2}$这里的状态很相似,我们要么在读非数字,要么在读数字。但是我们不会在每个字符后自动切换状态;我们只在非数字后面得到一个数字时才这样做,反之亦然。另外,我们必须跟踪当前重复字符串和当前重复计数中的所有字符。我已经将州国旗压缩到重复字符串中,但这里没有其他需要技巧的地方。在
任何解决方案的关键都是将内容拆分为要重复的字符串对,并重复计数,然后在lock step中迭代这些对。在
如果您只需要单个字符字符串和个位数的重复计数,这只是将字符串分成两个字符对,您可以使用mshsayem的答案,或者使用切片(
s[::2]
是字符串,s[1::2]
是计数)。在但是如果你想把它推广到多字母字符串和多位数计数呢?在
好吧,不知怎么的,我们需要把字符串分为数字和非数字。如果我们能做到这一点,我们就可以像mshsayem的答案使用成对字符一样使用这些组对。在
结果证明我们可以很容易地做到这一点。在标准库中有一个很好的函数,叫做^{} ,它允许您根据任何函数将任何内容分组到运行中。还有一个函数^{} 区分数字和非数字。在
我们想要的是:
现在,我们用mshsayem压缩字符的方式压缩它:
^{pr2}$所以:
天真的方法(如果数字只有一个,字符也是一个):
解释不当:
术语/功能:
<expression> for <variable> in <iterable>
是{a6}string
连接iterable字符串流程:
zip()
用于生成字符和重复时间的元组。e、 g.('d','3'), ('s','5)
(zip()
)将调用iterable来生成元组。注意,对于每个元组,它将调用同一个iterable两次,因为我们的iterable是一个迭代器,这意味着它将前进两次)for in
将迭代元组。使用两个变量(c,d)
将把元组解压到d
仍然是一个字符串。int
正在使其成为整数<string> * integer
将重复string
和{join
将返回结果以下是多位数、多字符版本:
^{pr2}$顺便说一下,使用^{} 更好,就像shown by abarnert。在
相关问题 更多 >
编程相关推荐