如何在有序字典中获得正确数量的子元素?
Posted
技术标签:
【中文标题】如何在有序字典中获得正确数量的子元素?【英文标题】:How to get correct number of sub elements in ordered dictionary? 【发布时间】:2021-10-21 15:09:07 【问题描述】:我有以下 2 个类似的有序字典(即前面步骤的输出),唯一的区别是 dict1
只有一个名为 GROUP
的节点,dict2
有两个(0 和 1 类似图片中)
from collections import OrderedDict
dict1 = OrderedDict([('CATALOG',
OrderedDict([('GROUP',
OrderedDict([
('ZONE', '4'),
('LIGHT', 'Mostly Shady'),
('PLANT', [
OrderedDict([
('COMMON', 'Bloodroot'),
('BOTANICAL', 'Sanguinaria canadensis')]),
OrderedDict([
('COMMON', 'Columbine'),
('BOTANICAL', 'Aquilegia canadensis')])])]))]))])
dict2 = OrderedDict([('CATALOG',
OrderedDict([('GROUP', [
OrderedDict([
('ZONE', '3'),
('LIGHT', 'Mostly Shady'),
('PLANT', [
OrderedDict([
('COMMON', "Dutchman's-Breeches"),
('BOTANICAL', 'Dicentra cucullaria')]),
OrderedDict([
('COMMON', 'Ginger, Wild'),
('BOTANICAL', 'Asarum canadense')])])]),
OrderedDict([
('ZONE', '4'),
('LIGHT', 'Mostly Sunny'),
('PLANT', [
OrderedDict([
('COMMON', 'Marsh Marigold'),
('BOTANICAL', 'Caltha palustris')]),
OrderedDict([
('COMMON', 'Cowslip'),
('BOTANICAL', 'Caltha palustris')])])])])]))])
结构是这样的:
我在确定每个字典有多少组时遇到问题,我的尝试如下所示,显示 dict2
的正确组数为 2,但当只有一组时,dict1
显示为答案 3 .如果我使用循环打印每个组,dict2
打印 2 个orderedDict 是正确的,但dict1
打印其他不是GROUP
的子节点。我做错了什么。
>>> len(dict1['CATALOG']['GROUP'])
3
>>> len(dict2['CATALOG']['GROUP'])
2
>>> dict1['CATALOG']['GROUP'][0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 0
>>>
>>> dict2['CATALOG']['GROUP'][0]
OrderedDict([('ZONE', '3'), ('LIGHT', 'Mostly Shady')...
>>>
>>> dict2['CATALOG']['GROUP'][1] ...
OrderedDict([('ZONE', '4'), ('LIGHT', 'Mostly Sunny')...
>>> ...
>>> for group in dict1['CATALOG']['GROUP']:
... print(group)
...
ZONE
LIGHT
PLANT
>>> for group in dict2['CATALOG']['GROUP']:
... print(group)
...
OrderedDict([('ZONE', '3'), ('LIGHT', 'Mostly Shady')...
OrderedDict([('ZONE', '4'), ('LIGHT', 'Mostly Sunny')...
【问题讨论】:
dict1['CATALOG']['GROUP']
是一个包含 3 个键的字典,dict2['CATALOG']['GROUP']
是一个包含两个元素的列表。
顺便说一句,从 Python 3.6 开始,普通字典会记住它们的顺序,所以你不需要使用OrderedDict
。
感谢您的回答。因此,我需要确定字典何时只有键(将是一个 GROUP
)以及何时是具有多个元素的列表(表示多个 GROUP
)。我使用 OrderedDict 是因为上一步给出的输出不受我控制。
@GerCas 你想统计字典中的子元素吗?或者只是确定对象是否是列表?
@Elan-R 我想知道字典中有多少节点GROUP
。在@Barmar 的帮助下,我明白要做到这一点,我首先需要知道GROUP
是列表还是字典。知道了之后,我就可以统计出名为GROUP
的节点数了。如果是 dict 长度 =1,如果是列表长度 = 该列表中的元素数。
【参考方案1】:
检查dictX['CATALOG']['GROUP']
是否为列表。如果不是列表,则长度为 1。
group1_len = len(dict1['CATALOG']['GROUP']) if isinstance(dict1['CATALOG']['GROUP'], list) else 1
group2_len = len(dict2['CATALOG']['GROUP']) if isinstance(dict2['CATALOG']['GROUP'], list) else 1
如果您先将字典包装在一个列表中,它可能会进行所有进一步的处理。那么两个字典的结构就会相似,你就不需要继续使用条件了。
for d in (dict1, dict2):
if not isinstance(d['CATALOG']['GROUP'], list):
d['CATALOG']['GROUP'] = [d['CATALOG']['GROUP']]
【讨论】:
感谢您的回答,但dict1
和 dict2
是针对相同的先前过程生成的。一个名为 xmltodict
的库,它从 xml 文件中获取输入。似乎当文件只有一个 GROUP
时,生成字典值作为 OrderedDict,而不是像 dict1
中的 OrderedDict 列表
您可以使用isinstance()
来测试它是字典还是列表。如果是字典,那就只有一本。
优秀。这似乎对我有用,我试过测试是否是一个列表,dict1
给出false
,dict2
给出true
。 >>> isinstance(dict1['CATALOG']['GROUP'], list) False >>> isinstance(dict2['CATALOG']['GROUP'], list) True
优秀!!!然后你首先fix
字典的结构,然后len(dictX['CATALOG']['GROUP'])
将适用于任何类型的具有一个或多个组的字典。【参考方案2】:
dict1
的长度就是密钥本身。如果我们知道这个对象是Dict
类型,我们可以使用辅助方法来做一些工作。
您可以在开始时进行一些类型检查以确定对象的形状。这将告诉您基础形状是 Dict
(又名 1 项)还是 List
(又名,多个)。
# something with 1 item, dict rendering
dict1 = ...
# something with 2 items, list rendering
dict2 = ...
# helper method
def checkShape(dict):
length = 0
if isinstance(dict['CATALOG']['GROUP'], dict):
# we know len is 1
length = 1
else:
# we know len is >1
length = len(dict['CATALOG']['GROUP'])
return length
【讨论】:
太棒了!您的解决方案也可以正常工作。我只将参数更改为dictX
,因为仅使用dict
会出错,因为它与isinstance(dictX,dict)
中预期的元素type
混淆。非常感谢以上是关于如何在有序字典中获得正确数量的子元素?的主要内容,如果未能解决你的问题,请参考以下文章