我正在尝试从中读取数据并创建嵌套的字典字典。有一个类似的问题here,但我似乎无法弄清楚如何使解决方案适应我的特定问题。如果有人能够解决我的问题,我将非常感激。
基本上,我有一个看起来像这样的文件:
A 'abc' 12 0.001
B 'tex' 34 0.002
B 'tex' 78 0.005
E 'yet' 88 0.090
A 'abc' 22 0.120
我需要创建一个如下所示的复杂字典:
complete_dict = {A:{'abc':[[12, 0.001], [22, 0.120]]},
B:{'tex':[[34, 0.002], [78, 0.005]]},
E:{'yet':[[88, 0.090]]}}
我可以创建内部字典,但我无法弄清楚如何创建外部字典。这是我的内部词典的代码:
with open('data.txt', mode="r") as data_file:
fieldnames = ('character', 'string', 'value1', 'value2')
reader = csv.DictReader(data_file, fieldnames=fieldnames, delimiter="\t")
inner_dict = {}
for row in reader:
values = [int(row['value1']), float(row['value2'])]
string = row['string']
if string in inner_dict:
inner_dict[string].append(values)
else:
inner_dict[string] = values
有人可以解释如何创建外部字典吗?我唯一的想法是读取文件并创建内部字典,然后重新读取文件以创建外部字典。当然必须有一个更简单的方法吗?在此先感谢您的帮助!
答案 0 :(得分:6)
这是你想要完成的吗?
with open('data.txt', mode="r") as data_file:
fieldnames = ('character', 'string', 'value1', 'value2')
reader = csv.DictReader(data_file, fieldnames=fieldnames, delimiter="\t")
complete_dict = {}
for row in reader:
char_dict = complete_dict.setdefault(row['character'], {})
values_list = char_dict.setdefault(row['string'], [])
values = [int(row['value1']), float(row['value2'])]
values_list.append(values)
pprint.pprint(complete_dict)
请注意,在您的示例中,您需要'value2'才能获得'value1'。此外,这似乎包括字符串周围的单引号作为字符串的一部分,因此您可能需要清理它。
答案 1 :(得分:2)
假设:
$ cat data.txt
A 'abc' 12 0.001
B 'tex' 34 0.002
B 'tex' 78 0.005
E 'yet' 88 0.090
A 'abc' 22 0.120
此:
import csv
d={}
with open('data.txt', mode="r") as data_file:
fieldnames = ('character', 'string', 'value1', 'value2')
reader = csv.DictReader(data_file, fieldnames=fieldnames, delimiter="\t")
for row in reader:
c=row['character']
values = [int(row['value1']), float(row['value2'])]
s = row['string']
if c not in d: d[c]={}
if s not in d[c]: d[c][s] = []
d[c][s].append(values)
print d
产地:
{'A': {"'abc'": [[12, 0.001], [22, 0.12]]},
'B': {"'tex'": [[34, 0.002], [78, 0.005]]},
'E': {"'yet'": [[88, 0.09]]}}
答案 2 :(得分:2)
使用defaultdict。
from collections import defaultdict
complete_dict = defaultdict(lambda: defaultdict(list))
with open('data.txt', mode="rb") as data_file:
reader = csv.reader(data_file, delimiter="\t")
for c, s, v1, v in reader:
complete_dict[c][s].append([v1, v2])
答案 3 :(得分:0)
如果您为了简洁而在名为s
的变量中读取该文件,则以下内容可能有效:
d = {}
for l in s.split('\n'):
character, string, val1, val2 = l.split('\t')
if not d.has_key(character):
d[character] = { string: [] }
d[character][string].append([val1, val2])
假设string
对于每个character
始终相同,但未在您的问题中明确指定。
答案 4 :(得分:0)
这是我将如何做到的。不比你的短。这种方式只保留内存中所有数据的一个副本,一次只从文件读取一行。
f = open('data.txt', 'r')
rows = imap(lambda line: line.split('\t'), f)
result = {}
for key1, key2, val1, val2 in rows:
key2 = eval(key2) # safe only if you know the value is a quoted string
if key1 not in result:
result[key1] = {}
if key2 not in result[key1]:
result[key1][key2] = []
result[key1][key2].append([int(val1), float(val2)])
f.close() # prevent lingering open file
答案 5 :(得分:0)
使用设置默认值:
with open('data.txt', mode="r") as data_file:
fieldnames = ('character', 'string', 'value1', 'value2')
reader = csv.DictReader(data_file, fieldnames=fieldnames, delimiter="\t")
result = {}
for row in reader:
result.setdefault(row['character'], {}).setdefault(row['string'], []).append([int(row['value1']), float(row['value2'])])
print(result)