【问题标题】:Writing a dictionary to a csv file with one line for every 'key: value'将字典写入 csv 文件,每个“键:值”一行
【发布时间】:2012-01-30 22:20:34
【问题描述】:

我有一本字典:

mydict = {key1: value_a, key2: value_b, key3: value_c}

我想将数据写入 dict.csv 文件,格式如下:

key1: value_a
key2: value_b
key3: value_c

我写道:

import csv
f = open('dict.csv','wb')
w = csv.DictWriter(f,mydict.keys())
w.writerow(mydict)
f.close()

但是现在我在一行中拥有所有键,在下一行中拥有所有值..

当我设法写出这样的文件时,我也想将它读回新字典。

为了解释我的代码,字典包含来自 textctrls 和复选框的值和布尔值(使用 wxpython)。我想添加“保存设置”和“加载设置”按钮。 保存设置应以上述方式将字典写入文件(使用户更容易直接编辑 csv 文件),加载设置应从文件中读取并更新 textctrls 和复选框。

【问题讨论】:

  • 你能提供一个更好的例子来说明你想要什么作为输出吗?你上面的“风格”不是CSV。你在找key1, value_a [linebreak] key2, value_b [linebreak] key3, value_c吗?
  • 另一种方法是使用repr() 写出字典,然后在读入时评估字符串。查看old SO post 以讨论str()repr() ,还有the docs
  • 除了我在下面的回答之外,如果您更喜欢比普通 CSV 文件更复杂的东西,您可能需要查看ConfigParser 模块
  • 你描述的是典型的csv模块写出来的csv格式。如果您用相同的键写出多个字典,则键只写一次,在第一行,每个字典一行对应的值,按照与第 1 行中的键对齐的正确顺序。

标签: python csv dictionary


【解决方案1】:

DictWriter 无法按您预期的方式工作。

with open('dict.csv', 'w') as csv_file:  
    writer = csv.writer(csv_file)
    for key, value in mydict.items():
       writer.writerow([key, value])

回读:

with open('dict.csv') as csv_file:
    reader = csv.reader(csv_file)
    mydict = dict(reader)

相当紧凑,但它假定您在阅读时不需要进行任何类型转换

【讨论】:

  • Mmh... 刚刚注意到您想要一种不完全类似于 CSV 的特定格式。假设您想要 CSV 样式(即每个键值对一行),因为您使用的是 CSV 模块...
  • 或者...如果 CSV 方法正是您想要的,但您更喜欢 ":" 作为分隔符,只需在创建写入器和读取器时添加 delimiter=':' :)
  • 注意,你应该在写和读之间关闭文件。看看这个问题/答案中发生了什么:stackoverflow.com/a/38467563/235698
  • @MarkTolonen 当然,使用with 会更好。我将更改示例以反映它...
  • @DareYang 抱歉耽搁了。实际上,我不知道我当时为什么写它。这不是必需的。编写时,这样做的效果是不翻译换行符(即,如果你写\n,你会在文件中得到\n)。如果不理会,“通用模式”就会启动,换行符会被转换为当前操作系统的默认值。鉴于它在这里不是很有用(除非你想有可预测的换行符),我会删除它。
【解决方案2】:

只是提供一个选项,也可以使用 pandas 包将字典写入 csv 文件。对于给定的示例,它可能是这样的:

mydict = {'key1': 'a', 'key2': 'b', 'key3': 'c'}

import pandas as pd

(pd.DataFrame.from_dict(data=mydict, orient='index')
   .to_csv('dict_file.csv', header=False))

要考虑的主要事情是在from_dict 方法中将'orient' 参数设置为'index'。这使您可以选择是否要将每个字典键写入新行。

另外,在to_csv 方法中,header 参数设置为 False 只是为了只有字典元素没有烦人的行。您始终可以在 to_csv 方法。

您的输出将如下所示:

key1,a
key2,b
key3,c

如果您希望键是列的名称,只需使用默认的“orient”参数,即“columns”,您可以查看文档链接。

【讨论】:

  • 优秀的工作就像一个魅力:)。我的值是一个列表,它生成了我的 csv,其中包含多个单元格中的所有列表值,并映射到第一列中的键。
  • 关于“作为列名的键”的最后一句话不完整。当使用 'orient=columns' 时,pandas 需要 {k:[v]} 字典。因此,首先将 dict 转换为这种格式,例如用d = {k: [v] for k, v in mydict.items()} 然后做pd.DataFrame.from_dict(data=d, orient='columns')
【解决方案3】:

最简单的方法是忽略 csv 模块并自行格式化。

with open('my_file.csv', 'w') as f:
    [f.write('{0},{1}\n'.format(key, value)) for key, value in my_dict.items()]

【讨论】:

  • 如果你的key 有一个逗号,你会过得很糟糕。
  • 我发现使用csv.writer(...).writerows(my_dict.items()) 更容易。 csv 模块不仅仅是添加逗号和换行符。
【解决方案4】:
outfile = open( 'dict.txt', 'w' )
for key, value in sorted( mydict.items() ):
    outfile.write( str(key) + '\t' + str(value) + '\n' )

【讨论】:

  • 请在您的回答中提供一些信息或cmets。
【解决方案5】:

你能做到吗:

for key in mydict.keys():
    f.write(str(key) + ":" + str(mydict[key]) + ",");

这样你就可以拥有

key_1:value_1,key_2:value_2

【讨论】:

  • 更好的是','.join("%s:%s" % (k,v) for k,v in mydict.items()) - 你通常最好迭代一个字典的项目,它给你一个键和值,而不是一个字典的键和做'n'值查找。 ','.join(...) 只负责在值之间放置逗号,而不添加额外的尾随逗号。
  • 请注意,此 python 代码的末尾不需要分号
【解决方案6】:

我个人一直觉得 csv 模块有点烦人。我希望其他人会向您展示如何巧妙地做到这一点,但我快速而肮脏的解决方案是:

with open('dict.csv', 'w') as f:  # This creates the file object for the context 
                                  # below it and closes the file automatically
    l = []
    for k, v in mydict.iteritems(): # Iterate over items returning key, value tuples
        l.append('%s: %s' % (str(k), str(v))) # Build a nice list of strings
    f.write(', '.join(l))                     # Join that list of strings and write out

但是,如果您想将其重新读入,则需要进行一些烦人的解析,尤其是当它全部位于一行时。这是使用您建议的文件格式的示例。

with open('dict.csv', 'r') as f: # Again temporary file for reading
    d = {}
    l = f.read().split(',')      # Split using commas
    for i in l:
        values = i.split(': ')   # Split using ': '
        d[values[0]] = values[1] # Any type conversion will need to happen here

【讨论】:

  • 我会接受里卡多的回答。或者至少使用单独的行。
【解决方案7】:
#code to insert and read dictionary element from csv file
import csv
n=input("Enter I to insert or S to read : ")
if n=="I":
    m=int(input("Enter the number of data you want to insert: "))
    mydict={}
    list=[]
    for i in range(m):
        keys=int(input("Enter id :"))
        list.append(keys)
        values=input("Enter Name :")
        mydict[keys]=values

    with open('File1.csv',"w") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=list)
        writer.writeheader()
        writer.writerow(mydict)
        print("Data Inserted")
else:
    keys=input("Enter Id to Search :")
    Id=str(keys)
    with open('File1.csv',"r") as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            print(row[Id]) #print(row) to display all data

【讨论】:

  • 加一点解释就更好了
【解决方案8】:

您是否尝试过像这样在w.writerow(mydict) 上添加“s”:w.writerows(mydict)?这个问题发生在我身上,但对于列表,我使用的是单数而不是复数。

【讨论】:

    猜你喜欢
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2023-03-03
    相关资源
    最近更新 更多