我以前在 python 中使用过字典,但我对 python 还是个新手。这次我使用的是一个字典的字典...即一个三层字典,并且想在编程之前进行检查。
我想将所有数据存储在这个三层字典中,并且想知道什么是一种很好的 pythonic 方式来初始化,然后读取文件并写入这样的数据结构。
我要的字典是以下类型:
{'geneid':
{'transcript_id':
{col_name1:col_value1, col_name2:col_value2}
}
}
数据是这种类型的:
geneid\ttx_id\tcolname1\tcolname2\n
hello\tNR432\t4.5\t6.7
bye\tNR439\t4.5\t6.7
关于如何以好的方式做到这一点有什么想法吗?
谢谢!
最佳答案
首先,让我们从 csv
开始处理解析行的模块:
import csv
with open('mydata.txt', 'rb') as f:
for row in csv.DictReader(f, delimiter='\t'):
print row
这将打印:
{'geneid': 'hello', 'tx_id': 'NR432', 'col_name1': '4.5', 'col_name2': 6.7}
{'geneid': 'bye', 'tx_id': 'NR439', 'col_name1': '4.5', 'col_name2': 6.7}
因此,现在您只需要将其重新组织成您喜欢的结构即可。这几乎是微不足道的,除了你必须处理这样一个事实,即第一次看到给定的 geneid
你必须为它创建一个新的空 dict
,同样这是您第一次在 geneid
中看到给定的 tx_id
。你可以用 setdefault
解决这个问题:
import csv
genes = {}
with open('mydata.txt', 'rb') as f:
for row in csv.DictReader(f, delimiter='\t'):
gene = genes.setdefault(row['geneid'], {})
transcript = gene.setdefault(row['tx_id'], {})
transcript['colname1'] = row['colname1']
transcript['colname2'] = row['colname2']
您可以使用 defaultdict
使其更具可读性:
import csv
from collections import defaultdict
from functools import partial
genes = defaultdict(partial(defaultdict, dict))
with open('mydata.txt', 'rb') as f:
for row in csv.DictReader(f, delimiter='\t'):
genes[row['geneid']][row['tx_id']]['colname1'] = row['colname1']
genes[row['geneid']][row['tx_id']]['colname2'] = row['colname2']
这里的技巧是顶级 dict
是一个特殊的 dict
每当它第一次看到一个新键时返回一个空的 dict
......并且那个空的 它返回的 dict
本身就是一个空的 dict
。唯一困难的部分是 defaultdict
需要一个返回正确类型对象的函数,而返回一个 defaultdict(dict)
的函数必须用一个 partial
、lambda
或显式函数。 (在 ActiveState 上有一些方法,在 PyPI 上有一些模块,它们会给你一个更通用的版本,如果你愿意的话,可以根据需要一直创建新的字典。)
关于python - 在 Python 中初始化/创建/填充字典的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15147740/