我正在使用csv.DictReader()读取文件。它实际上返回一个字典列表,而不是一个字典。如何强制它返回单个字典,或者如何合并它返回的字典列表?
def agilent_e8361c_pna_read(file_loc):
'''
Load the '.s2p' file in to a dictionary.
'''
with open(file_loc) as f:
# define the fields in the Agilent '.s2p' file
col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]
# read the data into a dictionary
s2p_dicts = csv.DictReader(itertools.ifilter(n_input.is_comment, f), fieldnames=col_names, delimiter=' ')
return s2p_dict
理想情况下,数据最初会被读入单个字典,永远不需要合并。这是一组数据。这些列属于一起,并且在没有完整集或相干子集的情况下是无意义的。如果DictReader没有“蟒蛇”能够胜任这一专长,我将决定合并词典列表。这应该不是科学家和程序员都喜欢用数据集做的不寻常的事情。
答案 0 :(得分:4)
如果你想要key:listOfValues
的词典,你可以这样做:
def transposeDict(listOfDicts):
"""Turn a list of dicts into a dict of lists. Assumes all dicts in the list have the exact same keys."""
keys = listOfDicts[0].iterkeys()
return dict((key, [d[key] for d in listOfDicts]) for key in keys)
或者,在python2.7或更高版本中:
def transposeDict(listOfDicts):
"""Turn a list of dicts into a dict of lists. Assumes all dicts in the list have the exact same keys."""
keys = listOfDicts[0].iterkeys()
return {key: [d[key] for d in listOfDicts] for key in keys}
当然,这假设列表中的所有dicts都具有完全相同的密钥 - 它们将来自DictReader。
一般情况下,如果情况并非如此,则需要执行类似
的操作from collections import defaultdict
def transposeListOfDicts(listOfDicts):
"""Turn a list of dict into a dict of lists"""
result = defaultdict(list)
for d in listofDicts:
for key, value in d.iteritems():
result[key].append(item)
return result
如果您希望占位符显示缺失值,则它看起来像这样:
def transposeListOfDicts(listOfDicts):
keys = {}
for d in listOfDicts:
keys.update(d.iterkeys())
return {key: [d.get(key, None) for d in listOfDicts] for key in keys}
答案 1 :(得分:3)
DictReader
会使每一行定期csv.reader()
返回,并根据您传入或从第一行读取的字段名将其转换为字典。这是设计的。
如果您的输入文件只包含一个行,请通过在阅读器上调用next()
来返回该行:
def agilent_e8361c_pna_read(file_loc):
with open(file_loc) as f:
col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]
reader = csv.DictReader(itertools.ifilter(n_input.is_comment, f), fieldnames=col_names, delimiter=' ')
return next(reader)
请注意next()
调用应位于while
块内,否则文件将在您阅读之前关闭。
如果需要将行合并到一个字典中,则需要说明如何查看合并的数据。您可以轻松地将行合并到每个键的列表中:
import csv
def agilent_e8361c_pna_read(file_loc):
with open(file_loc) as f:
col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]
result = {k: [] for k in col_names}
reader = csv.reader(itertools.ifilter(n_input.is_comment, f), fieldnames=col_names, delimiter=' ')
for row in reader:
for k, v in zip(col_names, row):
result[k].append(v)
return result
此时我们不再需要DictReader
了,因为我们这里没有为每行构建字典。
答案 2 :(得分:1)
好的,这是最优雅的解决方案,任何人都有这个问题。
def agilent_e8361c_pna_read(file_loc):
'''
Load the '.s2p file in to a dictionary.
'''
with open(file_loc) as f:
# read the data into a dictionary
rows = csv.reader(itertools.ifilter(n_input.is_comment, f), delimiter=' ')
# transpose data
cols = transpose(rows)
# create a dictionary with intuitive key names
col_names = ["f","s11","arg_s11","s21","arg_s21","s12","arg_s12","s22","arg_s22"]
s2p_dict = dict(zip(col_names,cols))
return s2p_dict
def transpose(l):
return map(list, zip(*l))