如何从 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.DictReader
将行加载到常规 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)))
这是一种方式:
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.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"
}
}
您可以利用现有 csv.DictReader
class,但更改行 returns。为此,请将以下 class 添加到脚本的开头:
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
然后,使用 class 代替 csv.DictReader
:
csvReader = OrderedDictReader(f)
其余代码保持不变。
如何获得嵌套字典,其中键和子键的顺序与 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.DictReader
将行加载到常规 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)))
这是一种方式:
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.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"
}
}
您可以利用现有 csv.DictReader
class,但更改行 returns。为此,请将以下 class 添加到脚本的开头:
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
然后,使用 class 代替 csv.DictReader
:
csvReader = OrderedDictReader(f)
其余代码保持不变。