3

我正在努力提高我对itertools图书馆的了解,因为它通常很有用。为此,我正在尝试解决我遇到的一个面试难题。其中很大一部分涉及顺序计算一个数字中分组和重复数字的数量。例如,对于数字:

1223444556

我想:

[(1,1),(2,2),(1,3),(3,4),(2,5),(1,6)]

也就是说,从左到右,有1个一,2个二,1个三,以此类推。

这是我当前的代码:

from itertools import groupby
groups_first = [int(''.join(v)[0]) for k,v in groupby(str(1223444556))]
counts = [len(''.join(v)) for k,v in groupby(str(1223444556))]
zip(counts,groups_first)

它有效,但我想知道是否有更紧凑的方法可以绕过将两个列表压缩在一起。有什么想法吗?我认为这可能会在 groupby() 中执行某种 lambda 函数,但我还看不到它。

谢谢!

4

3 回答 3

2

我可能只是写

>>> n = 1223444556
>>> [(len(list(g)), int(k)) for k,g in groupby(str(n))]
[(1, 1), (2, 2), (1, 3), (3, 4), (2, 5), (1, 6)]
于 2013-01-31T04:11:23.510 回答
2

怎么样:

[(sum(1 for _ in v), int(k)) for k,v in groupby(str(1223444556))]
于 2013-01-31T04:11:25.297 回答
1

我可能会选择收藏:

>>> from collections import Counter
>>> c = Counter('1223444556')
>>> c.items()
[('1', 1), ('3', 1), ('2', 2), ('5', 2), ('4', 3), ('6', 1)]

如果订单很重要(正如您在评论中所说),这可能不再是最有效的方法。但为了充分考虑,您可以这样做:

>>> t = c.items()
>>> t = sorted(t)

如果你希望 y, x 被列为 x, y,你可以这样做:

>>> t = [(y, x) for x, y in t]
>>> print t
[(1, '1'), (2, '2'), (1, '3'), (3, '4'), (2, '5'), (1, '6')]

这种方法的一个价值是重复的元素被列为一个字符串,所以不会混淆哪个数字来自原始列表,哪个数字表示频率。

于 2013-01-31T04:13:29.603 回答