0

我在运行 Python 2.7.3 的 Windows 7 x64 工作站上。

我有一个包含项目 ID 行的 CSV 文件,每一行属于一个组 ID,如下所示:

GroupID ItemID
a   1
a   2
a   3
b   4
b   5
b   6
c   7
c   8
c   9
etc…    

我需要做的是生成一个元组列表,其中每个元组是 GroupID 的字符串和与 GroupID 关联的每个 ItemID 的列表,如下所示:

[('a', [1, 2, 3]), ('b', [4, 5, 6]), ('c', [7 , 8, 9])]

到目前为止,我已经考虑过使用函数或列表来设置转换以对 GroupID 列进行重复数据删除,然后在第二个循环中进行某种比较 if 语句。有人可以给我一些建议吗?谢谢!

4

2 回答 2

1

您正在寻找itertools.groupby()

创建一个从可迭代对象返回连续键和组的迭代器。键是计算每个元素的键值的函数。如果未指定或为 None,则 key 默认为标识函数并返回未更改的元素。通常,iterable 需要已经在相同的 key 函数上排序。

例如:

import csv
from itertools import groupby
from operator import itemgetter

with open("test.csv") as file:
    reader = csv.reader(file)
    next(reader) #Skip header
    data = groupby(reader, itemgetter(0))
    print([(key, [item for _, item in items]) for key, items in data])

我们将它与operator.itemgetter()表示我们想按行中的第一项分组,然后我们使用嵌套列表推导来提取我们想要的数据。

这给了我们:

[('a', ['1', '2', '3']), ('b', ['4', '5', '6']), ('c', ['7', '8', '9'])]

当然,除非你需要一个列表,否则最好在这里使用生成器表达式来懒惰地进行操作。(我们在这里使用列表推导来获得不错的输出)。

请注意,我假设您的文件是逗号分隔的,就像您说的那样,而不是您的示例中所示。如果它是制表符分隔的,请使用csv.reader(file, dialect=csv.excel_tab)它来正确解析它。

于 2013-02-01T01:35:05.010 回答
0

如果分组键是连续的,那么类似于:

from itertools import groupby
from operator import itemgetter

data = [('a', 1), ('a', 2), ('b', 3), ('b', 5)]

grouped = [(k, map(itemgetter(1), g)) for k, g in groupby(data, itemgetter(0))]
# [('a', [1, 2]), ('b', [3, 5])]

否则,使用collections.defaultdict.

于 2013-02-01T01:37:46.800 回答