使用Python将CSV列拆分为单独数据结构的最优雅方法?

时间:2010-05-04 20:55:15

标签: python data-structures csv

我正在尝试接收Python。作为学习过程的一部分,我将用Java编写的项目移植到Python中。我现在在一个部分,我有一个表格的CSV标题列表:

headers = [a, b, c, d, e, .....]

和单独的组列表,这些标题应该被分解,例如:

headers_for_list_a = [b, c, e, ...]
headers_for_list_b = [a, d, k, ...]
. . .

我想获取CSV数据并根据这些组将其转换为dict,例如:

list_a = [
          {b:val_1b, c:val_1c, e:val_1e, ... },
          {b:val_2b, c:val_2c, e:val_2e, ... },
          {b:val_3b, c:val_3c, e:val_3e, ... },
          . . . 
         ]

例如,val_1b是'b'列的第一行,val_3c是'c'列的第三行,等等。

我的第一个“Java本能”是做类似的事情:

for row in data:
    for col_num, val in enumerate(row):
        col_name = headers[col_num]
        if col_name in group_a:
            dict_a[col_name] = val
        elif headers[col_cum] in group_b:
            dict_b[col_name] = val
        ...
    list_a.append(dict_a)
    list_b.append(dict_b)
    ...     

然而,这种方法似乎效率低下/不实用,并且不具备Python程序员经常谈论的优雅。有没有更像“禅宗”的方式我应该尝试 - 保持Python的哲学?

3 个答案:

答案 0 :(得分:5)

尝试Python的CSV模块,特别是DictReader类。

答案 1 :(得分:2)

没有必要以最pythonic的方式实现与代码相同的东西,但是由于使用了生成器表达式,这个版本的代码更简洁:

from itertools import izip

for row in data:
    dict_a = dict((col_name, val) for col_name, val in izip(headers, row) \
                  if col_name in group_a)
    dict_b = dict((col_name, val) for col_name, val in izip(headers, row) \
                  if col_name in group_b)
    list_a.append(dict_a)
    list_b.append(dict_b)

此外,使用group_agroup_b而不是列表的集合 - in运算符在集合上运行得更快。但Jason Humber是对的,DictReader更优雅,请看以下版本:

from csv import DictReader

for row in DictReader(your_file, headers):
    dict_a = dict((k, row[k]) for k in group_a)
    dict_b = dict((k, row[k]) for k in group_b)
    list_a.append(dict_a)
    list_b.append(dict_b)

答案 2 :(得分:2)

csv.DictReader

import csv

groups = dict(a=headers_for_list_a, b=headers_for_list_b)
lists = dict((name, []) for name in groups)

for row in csv.DictReader(csvfile, fieldnames=headers):
    for name, grp_headers in groups.items():
        lists[name].append(dict((header, row[header]) for header in grp_headers))
相关问题