我在运行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语句。请问有人给我一些建议吗?谢谢!
答案 0 :(得分:1)
您正在寻找itertools.groupby()
:
创建一个从中返回连续键和组的迭代器 迭代。关键是计算每个键值的函数 元件。如果未指定或为None,则键默认为标识 function并返回元素不变。一般来说,可迭代 需要已经在相同的键功能上排序。
例如:
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()
结合起来说我们想要按行中的第一项进行分组,然后我们使用嵌套的list comprehension来提取我们想要的数据。
这给了我们:
[('a', ['1', '2', '3']), ('b', ['4', '5', '6']), ('c', ['7', '8', '9'])]
当然,除非你需要一个列表,否则最好在这里使用生成器表达式来懒惰地执行操作。 (我们在这里使用列表推导来获得不错的输出)。
请注意,我假设您的文件以逗号分隔,就像您说的那样,而不是示例中所示。如果它的标签分开,请使用csv.reader(file, dialect=csv.excel_tab)
正确解析它。
答案 1 :(得分: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
。