【问题标题】:python create list of nested dictspython创建嵌套字典列表
【发布时间】:2016-12-18 14:37:22
【问题描述】:

我正在使用 beautifulsoup 来获取 XML 数据并将其放入一个字典数组中。但是,它没有按预期工作。相同的 dict 只是被添加到列表中。如何在嵌套 for 循环的正确阶段将正确的 dict 添加到列表中?

打印出来的列表应该如下所示:

[OrderedDict([('name', ‘dogs’), ('type', ‘housed’), ('value', ‘123’)]),
 OrderedDict([('name', ‘cats’), ('type', ‘wild’), ('value', ‘456’)]),
 OrderedDict([('name', ‘mice’), ('type', ‘housed’), ('value', ‘789’)])]

将它放在字典而不是列表中更好吗?

Here is the XML:
<window>
    <window class="Obj" name="ray" type="housed">
        <animal name="dogs",  value = "123" />
        <species name="sdogs",  value = "s123" />
    </window>
    <window class="Obj" name="james" type="wild">
        <animal name="cats", type="wild", value = "456" />
        <species name="scats", type="swild", value = "s456" />
    </window>
    <window class="Obj" name="bob" type="housed">
        <animal name="mice",  value = "789" />
        <species name="smice",  value = "s789" />
    </window>
</window>

这是代码(抱歉,如果有一些错误,我可以纠正它们,因为这是一个更大的代码示例):

import sys
import pprint
from bs4 import BeautifulSoup as bs
from collections import OrderedDict

soup = bs(open("test.xml"),"lxml")
dicty = OrderedDict()
listy = [];
Objs=soup.findAll('window',{"class":"Obj"})

#print Objs
for Obj in Objs:
    Objarr =  OrderedDict()     #### move this down
    #I want to add data to the array here:
    #print Obj
    for child in Obj.children:
        Objarr.update({"namesss" : Obj['name']})
        if child.name is not None:
            if child.name == "species":
                print Obj['name']
                print child['value']
                #Also, adding data to the array here:
                Objarr.update({"name" : Obj['name']})
                Objarr.update({"type" : Obj['type']})
                Objarr.update({"value": child['name']})
    listy.append(Objarr)        #### dedent this

pprint.pprint(listy)

【问题讨论】:

  • 请添加一些Objs 内容的示例以及预期的listy。
  • 是的,现在这样做:)
  • hist ettanany ive 添加了返回的列表对象。
  • 您还需要添加一些Objs 内容的示例。
  • touche,我看到了那个请求,现在就这样做

标签: python list dictionary beautifulsoup


【解决方案1】:

您正在更新字典并将其附加到列表中。结果是你一次又一次地使用同一个字典。您应该在子循环开始之前创建一个新字典并在循环之后添加,而不是在里面。

我猜是这样的:

import sys
import pprint
from bs4 import BeautifulSoup as bs
from collections import OrderedDict

soup = bs(open("my.xml"),"lxml")
dicty = OrderedDict()
listy = [];
Objs=soup.findAll('window',{"class":"Obj"})
#print Objs
for Obj in Objs:
    Objarr =  OrderedDict()        #### move this down ####
    #I want to add data to the array here:
    for child in Obj.children:
        if child.name is not None:
            if child.name == "variable":
               #Also, adding data to the array here:
                Objarr.update({"name" : Obj['text']})
                Objarr.update({"type" : " matrix”})
                Objarr.update({"value": child['name']})
    listy.append(Objarr)           #### dedent this ####

pprint.pprint(listy)

【讨论】:

  • 不,我没有足够的输入来测试它(这就是我写I guess的原因)。但是原始帖子中的listy.append 似乎不正确,因为它不断添加相同的 OrderedDict 并创建一个包含同一对象的许多实例的列表。我的示例展示了如何 (1) 创建一个新的 OrderedDict,(2) 向其中添加内容以及 (3) 将其添加到列表中。
  • 从 OP 复制的答案中有错误。
  • @Nurzhan 很可能有错误,但我的 cmets 突出显示的两个更正解决了这个问题:应用于真实代码的相同更改(问题中的代码既不完整也不工作)将解决问题
  • 非常感谢,这是正确答案。我已经更新了我的代码,因为它有很大的错误,对此感到抱歉。仍然 stenci 设法确定了问题。谢谢:)
  • 我很高兴它有效 :) 关于 StackOverflow 的一点建议:您不应该修改问题,否则答案对未来的读者毫无意义。您可以添加一个部分,其中包含与 cmets 或答案相关的进一步解释。
【解决方案2】:

查看以下内容以了解您的 objs 包含的内容:

>>> soup = bs(open("my_xml.xml"),"lxml")
>>>
>>> objs = soup.findAll('window',{"class":"Obj"})
>>>
>>> for obj in objs:
...     for child in obj.children:
...         print child
...


<animal name="dogs" type="housed" value="123"></animal>


<animal name="cats" type="wild" value="456"></animal>


<animal name="mice" type="housed" value="789"></animal>


<window>
</window>

表示objs 中的第一个元素是\n,最后一个元素是&lt;window&gt;\n&lt;/window&gt;,并且在其他元素之间有一个\n,用于分隔每两个元素。

要解决此问题,您需要将您的listiterator (obj.children) 转换为普通的list,例如list(obj.children),然后将这些值用于您的列表切片:start: 1, end: -2, step: 2,例如@987654332 @

这是本例中的输出:

>>> for obj in objs:
...     for child in list(obj.children)[1:-2:2]:
...         print child
...
<animal name="dogs" type="housed" value="123"></animal>
<animal name="cats" type="wild" value="456"></animal>
<animal name="mice" type="housed" value="789"></animal>

【讨论】:

  • 谢谢,我没有意识到你可以这样使用列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2021-11-20
  • 2021-04-19
  • 2018-01-16
相关资源
最近更新 更多