【问题标题】:Dictionary to CSV file: Ordering of columns字典到 CSV 文件:列的排序
【发布时间】:2015-07-06 07:21:00
【问题描述】:

我正在尝试将字典列表导出到 .csv 文件:

keys = hist[0].keys()
with open(file, 'wt') as output_file:
    dict_writer = csv.DictWriter(output_file, keys, lineterminator='\n')
    dict_writer.writeheader()
    dict_writer.writerows(hist)

我希望字典中的最后一个键成为列中的第一个键。

我的字典列表(hist)是:

[{'RSD': '-', 'GBP': '0.500409', 'Date': '2008-04-05'}, 
 {'RSD': '-', 'GBP': '0.500409', 'Date': '2008-04-06'}, 
 {'RSD': '-', 'GBP': '0.50331', 'Date': '2008-04-07'}, 
 {'RSD': '-', 'GBP': '0.507939', 'Date': '2008-04-08'},
...

我得到的:

for x in dates:
    l = {}
    for y in currs:
        try:
            m = exrates.get_exrates(x)[y]
        except KeyError:
            m = '-'
        l[y] = m
    l['Date'] = x
    hist.append(l)

如何更改字典的顺序或更改列的顺序?

【问题讨论】:

  • 字典没有排序,所以字典中没有“last”键。

标签: python list csv dictionary


【解决方案1】:

使用您想要的顺序对标题进行硬编码。

keys = ['Date', 'RSD', 'GBP']
with open(file, 'wt') as output_file:
    dict_writer = csv.DictWriter(output_file, keys, lineterminator='\n')
    dict_writer.writeheader()
    dict_writer.writerows(hist)

当您希望 csv 具有特定格式时,首选硬编码。

【讨论】:

  • 如果你有 1000 列怎么办?
  • 您的答案可以通过docs 中的这句话来改进“fieldnames 参数是一个键序列,用于标识字典中的值传递的 顺序writerow() 方法写入csvfile。"
  • @PadraicCunningham:无论哪种方式,订单都必须在某个地方确定。将它传递给DictWriter 似乎是正确的地方。与此相比,使用 OrderedDict 是一个重量级的解决方案。
  • @Steven Rumbalski 如果操作人员想要按顺序排列字典,那么他们需要一个有序字典。如果他们以后不打算使用字典,那么他们根本不需要存储字典,他们可以在迭代时编写。
  • @PadraicCunningham:我对“字典中的最后一个键成为列中的第一个键”的理解是重要的是数据在文本文件中的显示方式。也许我错了。
【解决方案2】:

如果您想要排序和反转,请使用 OrderedDict:

from collections import OrderedDict

for x in dates:
    l = OrderedDict()
    for y in currs:
        try:
            m = exrates.get_exrates(x)[y]
        except KeyError:
            m = '-'
        l[y] = m
    l['Date'] = x
    hist.append(l)

要获得相反的顺序,请使用 reversed:

keys = list(reversed(list(hist[0].keys())))
print(keys)

如果你只想把最后一个键放在前面:

k = list(hist[0].keys())

keys = keys[-1] +  key[:-1]
print(keys)

您也可以使用dict.get 的理解:

for x in dates:
    l = OrderedDict((y, exrates.get_exrates(x).get(y, "-")) for y in currs)
    l['Date'] = x
    hist.append(l)

如果您要提供标头并且在随用随写后不想要有序的字典,假设 curr 是一个列表,您可以使用 curr 作为标头添加日期:

import csv

with open(file, 'wt') as output_file:
    wr = csv.writer(output_file)
    wr.writerow(["Date"] + currs)
    for x in dates:
        row = [x] + [exrates.get_exrates(x).get(y, "-") for y in currs]
        wr.writerow(row)

curr 中的元素是您用作标题的键,因此如果您只想将[exrates.get_exrates(x).get(y, "-") for y in currs] 的内容和x 写入日期下的第一列,则不需要存储字典.

【讨论】:

    【解决方案3】:

    (如果您不反对使用pandas)您可以通过简单地重新排序列来做到这一点,请查看最后一步:

    In [1]: import pandas as pd
    
    In [2]: x = [{'RSD': '-', 'GBP': '0.500409', 'Date': '2008-04-05'}, 
       ...:  {'RSD': '-', 'GBP': '0.500409', 'Date': '2008-04-06'}, 
       ...:  {'RSD': '-', 'GBP': '0.50331', 'Date': '2008-04-07'}, 
       ...:  {'RSD': '-', 'GBP': '0.507939', 'Date': '2008-04-08'},]
    
    In [3]: pd.DataFrame(x)
    Out[3]: 
             Date       GBP RSD
    0  2008-04-05  0.500409   -
    1  2008-04-06  0.500409   -
    2  2008-04-07   0.50331   -
    3  2008-04-08  0.507939   -
    
    In [4]: y = pd.DataFrame(x)
    
    In [5]: y = y[['RSD', 'GBP', 'Date']]
    
    In [6]: y
    Out[6]: 
      RSD       GBP        Date
    0   -  0.500409  2008-04-05
    1   -  0.500409  2008-04-06
    2   -   0.50331  2008-04-07
    3   -  0.507939  2008-04-08
    

    【讨论】:

    • 我和下一个人一样喜欢 pandas,但 OP 似乎没有使用它。
    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多