我有大量这种格式的元组列表。每个元组的第二个字段是类别字段。
[(1, 'A', 'foo'),
(2, 'A', 'bar'),
(100, 'A', 'foo-bar'),
('xx', 'B', 'foobar'),
('yy', 'B', 'foo'),
(1000, 'C', 'py'),
(200, 'C', 'foo'),
..]
将其分解为同一类别(A、B、C 等)的子列表的最有效方法是什么?
最佳答案
使用 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))
产量
[(1, 'A', 'foo'), (2, 'A', 'bar'), (100, 'A', 'foo-bar')]
[('xx', 'B', 'foobar'), ('yy', 'B', 'foo')]
[(1000, 'C', 'py'), (200, 'C', 'foo')]
或者,要将每个组作为子列表创建一个列表,您可以使用列表推导:
[list(group) for key,group in itertools.groupby(data,operator.itemgetter(1))]
itertools.groupby
的第二个参数是 itertools.groupby
应用于 data
中每个项目的函数(第一个参数)。它应该返回一个 key
。 itertools.groupby
然后将所有具有相同 key
的连续项目组合在一起。
operator.itemgetter(1)选取序列中的第二个项目。
例如,如果
row=(1, 'A', 'foo')
然后
operator.itemgetter(1)(row)
等于 'A'
。
正如@eryksun 在评论中指出的那样,如果元组的类别以某种随机顺序出现,那么您必须在应用 itertools.groupby
之前先对 data
进行排序。这是因为 itertools.groupy
只将具有相同键的 连续 项收集到组中。
要按类别对元组进行排序,请使用:
data2=sorted(data,key=operator.itemgetter(1))
关于python - 将元组列表拆分为同一元组字段的子列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8092877/