簡體   English   中英

如何在 Python 中創建復雜的字典結構?

[英]How to create complex dictionary structure in Python?

我正在嘗試從中讀取數據並創建字典的嵌套字典。 還有一個類似的問題在這里,但我似乎無法弄清楚如何適應解決我的具體問題。 如果有人可以向我解釋我的問題的解決方案,我將不勝感激。

基本上,我有一個看起來像這樣的文件:

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

有人可以解釋如何創建外部字典嗎? 我唯一的想法是讀取文件並創建內部字典,然后重新讀取文件以創建外部字典。 當然必須有更簡單的方法嗎? 在此先感謝您的幫助!

這是你想要完成的嗎?

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)

請注意,在您的示例中,您在需要“value1”的地方有“value2”。 此外,這似乎包括字符串周圍的單引號作為字符串的一部分,因此您可能需要清理它。

鑒於:

$ 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]]}}

使用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])

使用setdefault

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)

為簡潔起見,如果您在名為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總是相同的,但這沒有在您的問題中明確指定。

這是我將如何做到的。 不比你短多少。 這種方式只在內存中保留所有數據的一份副本,一次只能從文件中讀取一行。

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

暫無
暫無

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

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