【问题标题】:Convert a csv.DictReader object to a list of dictionaries?将 csv.DictReader 对象转换为字典列表?
【发布时间】:2015-06-08 14:04:19
【问题描述】:

一个csv文件names.csv有内容:

first_name last_name
Baked Beans
Lovely Spam
Wonderful Spam

我想将它读入字典列表,第一行包含键:

>>> import csv
>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Baked Beans
Lovely Spam
Wonderful Spam

但是reader的类型是csv.DictReader吗? 如何将reader 转换为字典列表? 谢谢。

【问题讨论】:

    标签: python csv dictionary


    【解决方案1】:

    csv.DictReader 创建一个 dictreader 对象,如标题中所述。此对象仅在文件打开且无法切片时可用。

    根据标题将对象转换为列表......

    list_of_dicts = list(your_dictreader_object)
    

    【讨论】:

      【解决方案2】:

      创建函数

      import csv
      
      
      def csv_to_dict(filename):
          result_list=[]
          with open(filename) as file_obj:
              reader = csv.DictReader(file_obj, delimiter=delimiter)
              for row in reader:
                  result_list.append(dict(row))
          return result_list
      

      并使用它:

      list_of_dicts = csv_to_dict('names.csv')
      

      【讨论】:

        【解决方案3】:
        import csv
        with open("in.csv") as csvfile:
            reader = csv.DictReader(csvfile,delimiter=" ")
            print(list(reader))
        [{'first_name': 'Baked', 'last_name': 'Beans'}, {'first_name': 'Lovely', 'last_name': 'Spam'}, {'first_name': 'Wonderful', 'last_name': 'Spam'}]
        

        如果分隔符实际上不是,,则需要指定" " 或其他任何内容。

        为了消除任何混淆,该代码也适用于 python3.6,唯一的区别是使用 DictReader 默认情况下会给出 Orderdicts

        In [1]: import csv
           ...: with open("in.csv") as csvfile:
           ...:     reader = csv.DictReader(csvfile, delimiter=" ")
           ...:     print(list(reader))
           ...:     
        [OrderedDict([('first_name', 'Baked'), ('last_name', 'Beans')]), OrderedDict([('first_name', 'Lovely'), ('last_name', 'Spam')]), OrderedDict([('first_name', 'Wonderful'), ('last_name', 'Spam')])]
        

        您可以完全一样地访问密钥,OrderedDict 只是保持密钥插入顺序:

        In [2]: import csv
           ...: with open("in.csv") as csvfile:
           ...:     reader = csv.DictReader(csvfile, delimiter=" ")
           ...:     for dct in reader:
           ...:         print(f"{dct['first_name']} {dct['last_name']}")
           ...:         
           ...:     
        Baked Beans
        Lovely Spam
        Wonderful Spam
        

        py3.6 实际上也是如此,所以如果出于某种原因你真的想要一个 dict:

        In [5]: import csv
           ...: with open("in.csv") as csvfile:
           ...:     reader = csv.DictReader(csvfile, delimiter=" ")
           ...:     for dct in map(dict, reader):
           ...:         print(dct)
           ...:         print(f"{dct['first_name']} {dct['last_name']}")
           ...:         
           ...:     
        {'first_name': 'Baked', 'last_name': 'Beans'}
        Baked Beans
        {'first_name': 'Lovely', 'last_name': 'Spam'}
        Lovely Spam
        {'first_name': 'Wonderful', 'last_name': 'Spam'}
        Wonderful Spam
        

        py3.6 中插入时的排序保留是一个实现细节,可能会发生变化,但如果我们有足够多的人使用它,它可能只需要保留 :)

        【讨论】:

        • Python 3.6 不正确,应该使用print([dict(d) for d in reader])
        • @MattFletcher,它在 py3.6 中运行良好,什么不适合你?是因为你看到了OrderedDict's吗?
        • 是的,因此无法正确迭代它。我不是 Python 大师,所以我可能会遗漏一些重要的东西,但我读到它们的工作方式在 py3.6 中已经改变——我一辈子都找不到 SO 线程......
        • @MattFletcher,我在答案中添加了更多内容,OrderDict 是,出于所有意图和目的,它只是一个字典,它只是维护插入顺序,因此对于您的 csv,您会看到列/键与它们在文件中出现的顺序相同。
        • 明白了。那就怪我自己的愚蠢;)感谢您的澄清,我一直在用Dict vs OrderedDict撞我的头!
        【解决方案4】:

        使用list():

        print(list(reader))
        

        演示:

        >>> with open('names.csv') as csvfile:
        ...     reader = csv.DictReader(csvfile, delimiter=" ")
        ...     print(list(reader))
        ... 
        [{'first_name': 'Baked', 'last_name': 'Beans'}, {'first_name': 'Lovely', 'last_name': 'Spam'}, {'first_name': 'Wonderful', 'last_name': 'Spam'}]
        

        【讨论】:

        • 如果csv文件有很多列怎么办?它将如何形成字典或列表
        • @HNSingh 列表中的字典会更长。在上面的示例中,仅有的列是 first_namelast_name
        猜你喜欢
        • 2021-06-28
        • 1970-01-01
        • 2017-12-04
        • 2018-07-15
        • 1970-01-01
        • 2017-04-23
        • 2021-10-13
        • 2011-11-03
        相关资源
        最近更新 更多