Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中初始化/创建/填充Dict的Dict_Python_Dictionary - Fatal编程技术网

在Python中初始化/创建/填充Dict的Dict

在Python中初始化/创建/填充Dict的Dict,python,dictionary,Python,Dictionary,我以前在python中使用过词典,但我对python还是新手。这一次我用的是一本字典的一本字典的一本字典的一本字典。。。i、 例如,一个三层dict,并希望在编程之前进行检查 我想将所有数据存储在这个三层dict中,我想知道什么是一种很好的Python方式来初始化,然后读取文件并写入这样的数据结构 我想要的词典类型如下: {'geneid': {'transcript_id': {col_name1:col_value1, col_name2:col_value2} } } 数据属于以下类型:

我以前在python中使用过词典,但我对python还是新手。这一次我用的是一本字典的一本字典的一本字典的一本字典。。。i、 例如,一个三层dict,并希望在编程之前进行检查

我想将所有数据存储在这个三层dict中,我想知道什么是一种很好的Python方式来初始化,然后读取文件并写入这样的数据结构

我想要的词典类型如下:

{'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
有没有什么好办法


谢谢

首先,让我们从处理行解析的模块开始:

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\u id
。您可以通过以下方法解决此问题:

您可以使用以下工具使其更具可读性:


这里的诀窍是,顶级的
dict
是一个特殊的函数,每当它第一次看到一个新键时,就会返回一个空的
dict
,而它返回的空
dict
本身就是一个空的
dict
。唯一困难的部分是
defaultdict
采用返回正确类型对象的函数,而返回
defaultdict(dict)
的函数必须使用
partial
lambda
或显式函数编写。(ActiveState上有一些配方,PyPI上有一些模块,它们将为您提供一个更通用的版本,如果您愿意的话,可以根据需要创建新的词典。)

我也在尝试寻找替代方案,并在stackoverflow中找到了这个同样不错的答案:

就我而言,基本上:

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

在为我的研究编写代码时,我必须经常这样做。您需要使用defaultdict包,因为它允许您通过简单的赋值在任何级别添加键:值对。回答你的问题后我会给你看。这是直接来源于我的一个程序。关注最后4行(不是注释),并通过块的其余部分跟踪变量,以查看它在做什么:

from astropy.io import fits #this package handles the image data I work with
import numpy as np
import os
from collections import defaultdict

klist = ['hdr','F','Ferr','flag','lmda','sky','skyerr','tel','telerr','wco','lsf']
dtess = []

for file in os.listdir(os.getcwd()):
    if file.startswith("apVisit"):
        meff = fits.open(file, mode='readonly', ignore_missing_end=True)
        hdr = meff[0].header
        oid = str(hdr["OBJID"]) #object ID
        mjd = int(hdr["MJD5"].strip(' ')) #5-digit observation date
        for k,v in enumerate(klist):
            if k==0:
                dtess = dtess+[[oid,mjd,v,hdr]]
            else:
                dtess=dtess+[[oid,mjd,v,meff[k].data]]
        #header extension works differently from the rest of the image cube
        #it's not relevant to populating dictionaries
#HDUs in order of extension no.: header, flux, flux error, flag mask, 
# wavelength, sky flux, error in sky flux, telluric flux, telluric flux errors,
# wavelength solution coefficients, & line-spread function
dtree = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
for s,t,u,v in dtess:
    dtree[s][t][u].append(v)
#once you've added all the keys you want to your dictionary, 
#set default_factory attribute to None 
dtree.default_factory = None
这是摘要版

  • 首先,对于n级字典,必须进行排序和转储 以[key_1,key_2, …,键n,值]
  • 然后,要初始化n级字典, 只需输入“defaultdict(lambda:”(减去引号)n-1次, 在末尾粘贴“defaultdict(list)”(或其他数据类型),然后 合上括号
  • 使用for循环附加到列表。*注意:当您访问数据值时 在最低级别,您可能需要键入my_dict[key_1][key_2] […][key_n][0]获取实际值,而不仅仅是数据描述 在其中键入
  • *编辑:当你的字典达到你想要的大小时,设置 默认工厂属性为“无”
  • 如果尚未将默认的\u工厂设置为“无”,则可以稍后通过键入类似my_dict[key\u 1][key\u 2][…][new\u key]=new\u value之类的内容或使用append()命令添加到嵌套字典中。您甚至可以添加其他字典,只要这些形式的赋值所添加的字典本身没有嵌套

    *
    警告!新添加的代码段的最后一行非常重要,您可以将默认的\u factory属性设置为None。您的电脑需要知道您何时完成了向字典的添加,否则它可能会继续在后台分配内存,以防耗尽RAM,直到程序停止。这是非常重要的一种。在我写下这个答案后不久,我通过艰苦的方式学会了这一点。这个问题困扰了我好几个月,我甚至不认为我是最终解决这个问题的人,因为我对内存分配一无所知。

    你是说“高效”吗就您的时间编码和维护而言,或者就执行它的CPU时间而言?对不起,好的一点,编码和维护…对于更多的列,您可以对col_name中的col_name执行
    :genes[row['geneid'].[row['transcript_id'].[col_name]=row[col_name]
    不使用
    functools.partial
    和执行
    genes=defaultdict(lambda:defaultdict(dict))是否有缺点
    ?@StevenRumbalski:partial
    lambda
    之间没有太大区别。我个人觉得前者更容易理解,因为我知道它只不过是在函数中绑定参数,而
    lambda
    可以做任何事情。但这是一个风格问题。我使用
    lambda
    when表达式才是最重要的;
    partial
    当中心函数是最重要的;
    def
    当它们都不够明显时。是的,当我说,“ActiveState上有一些配方,PyPI上有一些模块,它们将为您提供一个更通用的版本,如果您愿意的话,可以根据需要创建新的词典。”这就是我的意思。有几种不同的方法可以做到这一点(有些甚至像perl和JS一样,根据索引的类型神奇地创建字典或列表)。
    class AutoVivification(dict):
        """Implementation of perl's autovivification feature."""
        def __getitem__(self, item):
            try:
                return dict.__getitem__(self, item)
            except KeyError:
                value = self[item] = type(self)()
                return value
    
    from astropy.io import fits #this package handles the image data I work with
    import numpy as np
    import os
    from collections import defaultdict
    
    klist = ['hdr','F','Ferr','flag','lmda','sky','skyerr','tel','telerr','wco','lsf']
    dtess = []
    
    for file in os.listdir(os.getcwd()):
        if file.startswith("apVisit"):
            meff = fits.open(file, mode='readonly', ignore_missing_end=True)
            hdr = meff[0].header
            oid = str(hdr["OBJID"]) #object ID
            mjd = int(hdr["MJD5"].strip(' ')) #5-digit observation date
            for k,v in enumerate(klist):
                if k==0:
                    dtess = dtess+[[oid,mjd,v,hdr]]
                else:
                    dtess=dtess+[[oid,mjd,v,meff[k].data]]
            #header extension works differently from the rest of the image cube
            #it's not relevant to populating dictionaries
    #HDUs in order of extension no.: header, flux, flux error, flag mask, 
    # wavelength, sky flux, error in sky flux, telluric flux, telluric flux errors,
    # wavelength solution coefficients, & line-spread function
    dtree = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
    for s,t,u,v in dtess:
        dtree[s][t][u].append(v)
    #once you've added all the keys you want to your dictionary, 
    #set default_factory attribute to None 
    dtree.default_factory = None