【问题标题】:Writing to csv a dictionary with datetime.datetime object as keys将 datetime.datetime 对象作为键写入 csv 字典
【发布时间】:2020-03-09 09:15:54
【问题描述】:

我有一个字典,其中包含 datetime.datetime 对象作为键,我想将它们写入 csv 文件。但是,抛出以下错误:

Traceback (most recent call last):
  File "/Users/macbook/Documents/08_PYTHON/00_PROJECTS/Navps/code/scrape.py", line 179, in <module>
    writer.writerow(data)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/csv.py", line 154, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/csv.py", line 147, in _dict_to_list
    wrong_fields = rowdict.keys() - self.fieldnames
AttributeError: 'datetime.datetime' object has no attribute 'keys'

下面是我的代码:

csv_columns = ['Date','Fund Value']
try:
    with open(bof, 'w') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
        writer.writeheader()
        for data in csvdict:
            writer.writerow(data)
except IOError:
    print("I/O error")

这是csvdict 的样子:

csvdict = {datetime.datetime(2019, 1, 16, 0, 0): '2.8010', datetime.datetime(2019, 2, 8, 0, 0): '2.8295', datetime.datetime(2019, 2, 7, 0, 0): '2.8326',....}

在将 datetime.datetime 对象作为键处理时,我是否遗漏了什么?我真的很想把日期当作我的钥匙。这根本不可能吗?

注意:如果有帮助,我将在 Python 3.8 上运行此脚本

【问题讨论】:

    标签: python python-3.x csv datetime python-datetime


    【解决方案1】:

    您似乎误解了DictWriter 的工作原理; example 说你会写完整的字典,例如

    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
    

    而您拥有的是一本大键值字典。最好使用普通的csv.Writer

    csv_columns = ['Date','Fund Value']
    with open(bof, 'w') as csvfile:
        writer = csv.Writer(csvfile)
        writer.writerow(csv_columns)
        for date, value in csvdict.items():
            writer.writerow([date.isoformat(), value])
    

    我已经为您选择了 ISO-8601 作为日期格式,because it's the only right thing to do ;-)

    【讨论】:

    • 但我不明白:writer.writerow(data) 中的data 本身不是字典吗,因为数据基本上是字典列表中的单个字典元素csvdict
    • 不,您的 csvdict 是一个字典,其中键的日期时间和值的字符串,而不是字典列表。
    【解决方案2】:

    问题是csv.DictWriter 希望每一行都成为字典。因此,要使用它,您需要将csvdict 中的键值项对转换为行。使用内置的zip() 函数很容易:

    import csv
    import datetime
    
    
    bof = 'bof.csv'
    csvdict = {datetime.datetime(2019, 1, 16, 0, 0): '2.8010',
               datetime.datetime(2019, 2, 8, 0, 0): '2.8295',
               datetime.datetime(2019, 2, 7, 0, 0): '2.8326',}
    
    csv_columns = ['Date','Fund Value']
    try:
        with open(bof, 'w', newline='') as csvfile:
            writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
            writer.writeheader()
            for row in (dict(zip(csv_columns, item)) for item in csvdict.items()):
                writer.writerow(row)
    except IOError:
        print("I/O error")
    

    【讨论】:

    • 但我不明白:writer.writerow(data) 中的data 本身不是字典吗,因为数据基本上是字典列表中的单个字典元素csvdict
    • Nico: csvdict 是一个键值对字典(一如既往)。我的答案中的代码将它们中的每一个转换为适当格式的单独字典,以传递给writerow()
    【解决方案3】:

    DictWriter 用于编写字典列表:

    包含完全相同的键。

    您可以使用普通的 csv-writer:

    import datetime
    import csv
    
    bof = "somefile.csv"
    csvdict = {datetime.datetime(2019, 1, 16, 0, 0): '2.8010', 
               datetime.datetime(2019, 2, 8, 0, 0): '2.8295',
               datetime.datetime(2019, 2, 7, 0, 0): '2.8326'}
    csv_columns = ['Date','Fund Value']
    try:
        with open(bof, 'w') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(csv_columns)
            for key, value in csvdict.items():
                writer.writerow([key, value])
    except IOError:
        print("I/O error") 
    

    输出:

    Date,Fund Value
    2019-01-16 00:00:00,2.8010
    2019-02-08 00:00:00,2.8295
    2019-02-07 00:00:00,2.8326
    

    【讨论】:

    • for p, v in csvdict.items() 比单独访问 dict 来获取值更惯用(也更快)。
    猜你喜欢
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    • 2020-05-29
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多