簡體   English   中英

如何從csv構建嵌套的有序字典?

[英]How to build a nested ordered dict from a csv?

我怎樣才能得到一個嵌套的字典,其中兩個鍵和子鍵正是以相同的順序為csv文件?

我試過了

import csv
from collections import OrderedDict

filename = "test.csv"
aDict = OrderedDict()

with open(filename, 'r') as f:
    csvReader = csv.DictReader(f)
    for row in csvReader:
        key = row.pop("key")
        aDict[key] = row

在哪里test.csv看起來像

key,number,letter
eins,1,a
zwei,2,b
drei,3,c

但是子詞典沒有排序(行字母和數字已更改)。 那么如何以有序的方式填充aDict[key]

您必須自己從csv.reader返回的行(序列)構建字典和子字典,而不是使用csv.DictReader

幸運的是,這很容易:

import csv
from collections import OrderedDict

filename = 'test.csv'
aDict = OrderedDict()

with open(filename, 'rb') as f:
    csvReader = csv.reader(f)
    fields = next(csvReader)
    for row in csvReader:
        temp = OrderedDict(zip(fields, row))
        key = temp.pop("key")
        aDict[key] = temp

import json  # just to create output
print(json.dumps(aDict, indent=4))

輸出:

{
    "eins": {
        "number": "1",
        "letter": "a"
    },
    "zwei": {
        "number": "2",
        "letter": "b"
    },
    "drei": {
        "number": "3",
        "letter": "c"
    }
}

這是一種方法:

import csv
from collections import OrderedDict

filename = "test.csv"
aDict = OrderedDict()

with open(filename, 'r') as f:
    order = next(csv.reader(f))[1:]
    f.seek(0)

    csvReader = csv.DictReader(f)
    for row in csvReader:
        key = row.pop("key")
        aDict[key] = OrderedDict((k, row[k]) for k in order)

csv.DictReader將行加載到常規dict而不是有序dict 您必須手動將csv讀取到OrderedDict才能獲得所需的訂單:

from collections import OrderedDict

filename = "test.csv"
dictRows = []

with open(filename, 'r') as f:
    rows = (line.strip().split(',') for line in f)
    # read column names from first row
    columns = rows.next()
    for row in rows:
        dictRows.append(OrderedDict(zip(columns, row)))

您可以利用現有的csv.DictReader類,但可以更改其返回的行。 為此,請將以下類添加到腳本的開頭:

class OrderedDictReader(csv.DictReader):
    def next(self):
        # Get a row using csv.DictReader
        row = csv.DictReader.next(self)

        # Create a new row using OrderedDict
        new_row = OrderedDict(((k, row[k]) for k in self.fieldnames))
        return new_row

然后,使用此類代替csv.DictReader

csvReader = OrderedDictReader(f)

您的其余代碼保持不變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM