基于值在Python字典中选择对象

2024-09-28 18:55:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python的新手,决定从Matlab跳转。几天来我一直试图找到问题的答案,但没有成功!在

问题是:我有一堆具有特定属性的对象。请注意,我并不是在编程的意义上谈论对象和属性-我是指字面上的天文对象,我有不同类型的数值数据和物理属性。在

在脚本的一个循环中,我遍历目录中的每个源/对象,进行一些计算,并将结果粘贴到一个巨大的字典中。剧本的形式是这样的:

for i in range ( len(ObjectCatalogue) )

    calculate quantity1 for source i    

    calculate quantity2 for source i 

    determine attribute1 for source i 

    sourceDataDict[i].update( {'spectrum':quantity1} )

    sourceDataDict[i].update( {'peakflux':quantity2} )

    sourceDataDict[i].update( {'morphology':attribute1} )

因此,一旦我浏览了大约一百个源,我可以,比方说,使用spectrumSource20=sourceData[20]['spectrum']等访问20号物体的光谱

我想做的是能够选择字典中的所有对象,基于关键字“形态学”的值。所以说“形态学”的关键字可以采用“simple”或“complex”值。有没有什么我可以不用循环就可以做到的?一、 我能做些什么吗?比如创建一个新的字典,包含所有把“复杂”值作为“形态学”关键字的来源?在

很难解释,但是使用我习惯于用Matlab编写的逻辑索引,它看起来像

^{pr2}$

(其中*表示字典中的所有对象)

不管怎样-任何帮助都将不胜感激!在


Tags: 对象sourcefor字典属性update关键字spectrum
3条回答

没有一种直接的方法来索引无序的嵌套字典,就像您所希望的语法所希望的那样。但是,在Python中有几种方法可以实现,它们有不同的接口和性能特性。在

最好的解决方案可能是创建一个附加的字典,它根据您关心的任何特性进行索引。例如,要查找'morphology'值为'complex'的值,可以这样做:

from collections import defaultdict

# set up morphology dict (you could do this as part of generating the morphology)
morph_dict = defaultdict(list)
for data in sourceDataDict.values():
    morph_dict[data["morphology"]].append(data)

# later, you can access a list of the values with any particular morphology
complex_morph = morph_dict["complex"]

虽然这是高性能的,但需要提前为所有内容设置反向索引可能会很烦人。另一种方法可能是使用列表理解或生成器表达式迭代字典并找到适当的值:

^{pr2}$

我相信你正在处理一个类似于下面的结构

sourceDataDict = [
    {'spectrum':1,
    'peakflux':10,
     'morphology':'simple'
    },
    {'spectrum':2,
    'peakflux':11,
     'morphology':'comlex'
     },
    {'spectrum':3,
    'peakflux':12,
     'morphology':'simple'
     },
    {'spectrum':4,
    'peakflux':13,
     'morphology':'complex'
     }
    ]

你可以用列表理解来做类似的事情

^{pr2}$

使用itertools.ifilter,您可以获得类似的结果

>>> list(itertools.ifilter(lambda e:e.get('morphology',None) == 'complex', sourceDataDict))
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

请注意,使用get而不是索引是为了确保即使键“形态学”不存在,功能也不会失败。如果它确实存在,您可以将上面的内容重写为

>>> [e for e in sourceDataDict if e['morphology'] == 'complex']
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

>>> list(itertools.ifilter(lambda e:e['morphology'] == 'complex', sourceDataDict))
[{'morphology': 'complex', 'peakflux': 13, 'spectrum': 4}]

没有循环,没有。有list comprehension,是:

complex = [src for src in sourceDataDict.itervalues() if src.get('morphology') == 'complex']

如果sourceDataDict恰好是一个列表,则可以删除itervalues

^{pr2}$

如果您仔细考虑一下,计算*将意味着无论如何都有一个循环操作(假设它是有效的语法)。所以你的诀窍是对你所使用的数据结构进行最有效的循环。在

提高效率的唯一方法是提前索引所有数据对象的“形态”键,并使它们保持最新。在

相关问题 更多 >