制作列表oneliner -python列表

时间:2012-05-28 12:49:07

标签: python list

我有一个清单

l=[(1,2),(1,6),(3,4),(3,6),(1,4),(4,3)]

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

[[2,4,6],[4,6],[3]]

制作一个迭代列表并编写完整函数的程序很容易。 我想找到一个oneliner - python这样做的方式。 有什么想法吗?

2 个答案:

答案 0 :(得分: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]]

<强>解释

这可以通过使用itertools.groupby来实现。 groupby在iterable中找到连续组,通过键组对返回迭代器。

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

groupby原始订单中的元素进行分组,因此,如果您希望按列表中的第一个数字进行分组,则必须先对其进行排序,以便groupby可以通过第一个数字按升序排列并实际分组。

>>> sorted(L)
[(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (4, 3)]

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

[(1, <itertools._grouper object at 0x02BB7ED0>), (3, <itertools._grouper object at 0x02BB7CF0>), (4, <itertools._grouper object at 0x02BB7E30>)]

以下是按第一个数字分组的排序项目。 groupby将每个键的组作为迭代器返回,这非常有效且非常有效但是对于此示例,我们只需将其转换为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)])]

这几乎是正确的,但所需的输出只显示每个列表中组中的第二个数字。因此,以下方法可以达到预期的效果。

[[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]

答案 1 :(得分:2)

l = [(1, 2), (1, 6), (3, 4), (3, 6), (1, 4), (4, 3)]

d = {}
for (k, v) in l:
    d.setdefault(k, []).append(v)

print d.values()

我知道这不是一个班轮,但也许它比一个班轮更容易阅读。