Python 更有效地使用itertools.groupby()

Python 更有效地使用itertools.groupby(),python,itertools,Python,Itertools,我正在努力提高我对itertools库的知识,因为它非常有用。为此,我正试图解决我遇到的一个面试难题。它的很大一部分涉及对一个数字中分组和重复的数字进行顺序计数。例如,对于数字: 1223444556 我想: [(1,1),(2,2),(1,3),(3,4),(2,5),(1,6)] 也就是说,从左到右,有1个1,2个2,1个3,等等 这是我目前的代码: from itertools import groupby groups_first = [int(''.join(v)[0]) for

我正在努力提高我对
itertools
库的知识,因为它非常有用。为此,我正试图解决我遇到的一个面试难题。它的很大一部分涉及对一个数字中分组和重复的数字进行顺序计数。例如,对于数字:

1223444556
我想:

[(1,1),(2,2),(1,3),(3,4),(2,5),(1,6)]
也就是说,从左到右,有1个1,2个2,1个3,等等

这是我目前的代码:

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函数,但我还看不到它


谢谢

我可能只会写信

>>> 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)]
那么:

[(sum(1 for _ in v), int(k)) for k,v in groupby(str(1223444556))]

我可能会选择收藏:

>>> 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')]

此方法的一个价值是,重复元素以字符串形式列出,因此不会混淆哪个数字来自原始列表,哪个数字表示频率。

这很有效,但我还需要保留顺序。Uggghhh。为什么我总是对自己这么苛刻?这就是我拍摄的目的。我会尽快接受。不用着急,也许有人会想出更聪明的办法。我也喜欢@DavidRobinson的解决方案,它不需要构建列表。[除非它们非常大,否则我不必担心。]没错,我没有看到--我被:pbot是好的解决方案吓坏了,但顺便说一句,
timeit.timeit([(sum(1表示v中的u),int(k))表示k,v表示groupby(s)],setup=“s='1223444556';来自itertools导入groupby”,number=100000)
vs
timeit.timeit([(len(list(v)),int(k))表示k,v在groupby(s)]”,setup=“s='1223444556';from itertools import groupby”,number=100000)
表示我的方法快了30%左右。由于您下面的计时注释,我被接受了。不过,我会天真地选择@DSM的解决方案。谢谢大家!