制作列表oneliner -python列表

bac*_*m09 0 python list

我有一份清单

l=[(1,2),(1,6),(3,4),(3,6),(1,4),(4,3)]
Run Code Online (Sandbox Code Playgroud)

我想返回一个列表,其中包含每个元组中第一个数字的列表.像这样的东西:

[[2,4,6],[4,6],[3]]
Run Code Online (Sandbox Code Playgroud)

要创建一个迭代列表并编写完整函数的程序,这很容易.我想找到一个oneliner - python这样做的方式.有任何想法吗?

jam*_*lak 10

>>> from itertools import groupby
>>> from operator import itemgetter
>>> L = [(1,2), (1,6), (3,4), (3,6), (1,4), (4,3)]
>>> [[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
[[2, 4, 6], [4, 6], [3]]
Run Code Online (Sandbox Code Playgroud)

说明

这通过使用itertools.groupby.在iterable中groupby查找连续的组,通过键,组对返回迭代器.

赋予的参数groupby是一个关键函数,itemgetter(0)为每个元组调用,返回第一个项作为键groupby.

groupby原始顺序对元素进行分组,因此如果要按列表中的第一个数字进行分组,则必须先对其进行分类,以便groupby按升序顺序浏览第一个数字并对其进行分组.

>>> sorted(L)
[(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (4, 3)]
Run Code Online (Sandbox Code Playgroud)

有一个排序列表,您可以清楚地看到如果您回顾最终输出将创建的组.现在您可以groupby用来显示密钥,组对.

[(1, <itertools._grouper object at 0x02BB7ED0>), (3, <itertools._grouper object at 0x02BB7CF0>), (4, <itertools._grouper object at 0x02BB7E30>)]
Run Code Online (Sandbox Code Playgroud)

以下是按第一个数字分组的排序项目.groupby将每个键的组作为迭代器返回,这很棒且效率很高但是对于这个例子我们只是将它转换为a list以确保它正常工作.

>>> [(k, list(v)) for k,v in groupby(sorted(L), itemgetter(0))]
[(1, [(1, 2), (1, 4), (1, 6)]), (3, [(3, 4), (3, 6)]), (4, [(4, 3)])]
Run Code Online (Sandbox Code Playgroud)

这几乎是正确的,但所需的输出只显示每个列表中组中的第二个数字.因此,以下实现了期望的结果.

[[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
Run Code Online (Sandbox Code Playgroud)

  • 良好的心灵能力......我还是不明白! (2认同)