将元组列表拆分为同一元组字段的子列表

Kau*_*Zaw 19 python sorting grouping list

我有这种格式的巨大元组列表.每个元组的第二个字段是类别字段.

    [(1, 'A', 'foo'),
    (2, 'A', 'bar'),
    (100, 'A', 'foo-bar'),

    ('xx', 'B', 'foobar'),
    ('yy', 'B', 'foo'),

    (1000, 'C', 'py'),
    (200, 'C', 'foo'),
    ..]
Run Code Online (Sandbox Code Playgroud)

将其分解为同一类别(A,B,C等)的子列表的最有效方法是什么?

unu*_*tbu 23

使用itertools.groupby:

import itertools
import operator

data=[(1, 'A', 'foo'),
    (2, 'A', 'bar'),
    (100, 'A', 'foo-bar'),

    ('xx', 'B', 'foobar'),
    ('yy', 'B', 'foo'),

    (1000, 'C', 'py'),
    (200, 'C', 'foo'),
    ]

for key,group in itertools.groupby(data,operator.itemgetter(1)):
    print(list(group))
Run Code Online (Sandbox Code Playgroud)

产量

[(1, 'A', 'foo'), (2, 'A', 'bar'), (100, 'A', 'foo-bar')]
[('xx', 'B', 'foobar'), ('yy', 'B', 'foo')]
[(1000, 'C', 'py'), (200, 'C', 'foo')]
Run Code Online (Sandbox Code Playgroud)

或者,要创建一个列表,每个组作为子列表,您可以使用列表推导:

[list(group) for key,group in itertools.groupby(data,operator.itemgetter(1))]
Run Code Online (Sandbox Code Playgroud)

第二个参数itertools.groupby是一个itertools.groupby适用于data(第一个参数)中每个项目的函数.预计将返回key.itertools.groupby然后将所有相邻的项目组合在一起key.

operator.itemgetter(1)选择序列中的第二个项目.

例如,如果

row=(1, 'A', 'foo')
Run Code Online (Sandbox Code Playgroud)

然后

operator.itemgetter(1)(row)
Run Code Online (Sandbox Code Playgroud)

等于'A'.


正如@eryksun在评论中指出的那样,如果元组的类别以某种随机顺序出现,那么您必须data在应用之前先排序itertools.groupby.这是因为itertools.groupy只将具有相同键的连续项目收集到组中.

要按类别对元组进行排序,请使用:

data2=sorted(data,key=operator.itemgetter(1))
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记首先必须对数据进行排序:`data2 = sorted(data,key = operator.itemgetter(1))`. (6认同)