【问题标题】:Convert csv into list of dictionaries in python将csv转换为python中的字典列表
【发布时间】:2021-01-28 23:32:14
【问题描述】:

我有一个 CSV 文件,其中第一行是标题,然后其他行是列中的数据。

我正在使用 python 将这些数据解析到字典列表中

通常我会使用以下代码:

def csv_to_list_of_dictionaries(file):
    with open(file) as f:
        a = []
        for row in csv.DictReader(f, skipinitialspace=True):
            a.append({k: v for k, v in row.items()})
        return a

但由于一列中的数据存储在字典中,因此此代码不起作用(它分隔了此字典中的键:值对

所以我的 csv 文件中的数据如下所示:

col1,col2,col3,col4
1,{'a':'b', 'c':'d'},'bla',sometimestamp

由此创建的字典如下:{col1:1, col2:{'a':'b', col3: 'c':'d'}, col4: 'bla'}

我希望得到的结果是:{col1:1, col2:{'a':'b', 'c':'d'}, col3: 'bla', col4: sometimestamp}

【问题讨论】:

  • 关于 CSV 的标准并不多,但您的输入看起来有问题。如果您想在单个列中包含逗号,最常见的解决方案是引用整个值,例如1,"{'a':'b', 'c':'d'}",'bla',sometimestamp。您也许可以告诉csv 模块将大括号视为引号,但修复源代码也值得考虑。
  • 我认为quotechar只能是单个字符;您将无法执行csv.DictReader(f, quotechar="{}") 之类的操作。实际上,这也不是您想要的,因为大括号应该是解析结果的一部分。你能预处理文件并将{替换为"{}替换为}"吗?

标签: python list csv dictionary


【解决方案1】:

不要使用 csv 模块使用正则表达式从每一行中提取字段。然后根据提取的行制作字典。

示例文件:

col1,col2,col3,col4
1,{'a':'b', 'c':'d'},'bla',sometimestamp
2,{'a':'b', 'c':'d'},'bla',sometimestamp
3,{'a':'b', 'c':'d'},'bla',sometimestamp
4,{'a':'b', 'c':'d'},'bla',sometimestamp
5,{'a':'b', 'c':'d'},'bla',sometimestamp
6,{'a':'b', 'c':'d'},'bla',sometimestamp

.

import re
pattern = r'^([^,]*),({.*}),([^,]*),([^,]*)$'
regex = re.compile(pattern,flags=re.M)

def csv_to_list_of_dictionaries(file):
    with open(file) as f:
        columns = next(f).strip().split(',')
        stuff = regex.findall(f.read())
    a = [dict(zip(columns,values)) for values in stuff]
    return a

stuff = csv_to_list_of_dictionaries(f)

In [20]: stuff
Out[20]: 
[{'col1': '1',
  'col2': "{'a':'b', 'c':'d'}",
  'col3': "'bla'",
  'col4': 'sometimestamp'},
 {'col1': '2',
  'col2': "{'a':'b', 'c':'d'}",
  'col3': "'bla'",
  'col4': 'sometimestamp'},
 {'col1': '3',
  'col2': "{'a':'b', 'c':'d'}",
  'col3': "'bla'",
  'col4': 'sometimestamp'},
 {'col1': '4',
  'col2': "{'a':'b', 'c':'d'}",
  'col3': "'bla'",
  'col4': 'sometimestamp'},
 {'col1': '5',
  'col2': "{'a':'b', 'c':'d'}",
  'col3': "'bla'",
  'col4': 'sometimestamp'},
 {'col1': '6',
  'col2': "{'a':'b', 'c':'d'}",
  'col3': "'bla'",
  'col4': 'sometimestamp'}]

【讨论】:

  • 但这并不能解决将 {'a':'b', 'c':'d'} 放入仅第二列,而不是在第二列和第三列之间拆分
  • @marquillo - 你说得对,我一定没注意。对于那个很抱歉。请查看我的编辑。
  • 好的,所以我扩展了正则表达式模式,它对我有用,谢谢
  • @marquillo - 如何扩展正则表达式模式?如果您愿意,可以添加到我的答案中。
  • 你的正则表达式模式正好是四个“列”,所以我必须为我的 csv 文件中的列数准备它。所以代码有效,但不适用于随机列数。不管怎样,你给了我一个想法,这很重要。
猜你喜欢
  • 2020-01-03
  • 2019-04-11
  • 2014-04-24
  • 2019-02-10
  • 2015-07-23
  • 2018-06-23
  • 1970-01-01
  • 2018-12-09
  • 2021-07-31
相关资源
最近更新 更多