创建字典Python列表

l1t*_*1um 28 python dictionary list

我想iframe从网页上获取所有内容.

码:

site = "http://" + url
f = urllib2.urlopen(site)
web_content =  f.read()

soup = BeautifulSoup(web_content)
info = {}
content = []
for iframe in soup.find_all('iframe'):
    info['src'] = iframe.get('src')
    info['height'] = iframe.get('height')
    info['width'] = iframe.get('width')
    content.append(info)
    print(info)       

pprint(content)
Run Code Online (Sandbox Code Playgroud)

结果print(info):

{'src': u'abc.com', 'width': u'0', 'height': u'0'}
{'src': u'xyz.com', 'width': u'0', 'height': u'0'}
{'src': u'http://www.detik.com', 'width': u'1000', 'height': u'600'}
Run Code Online (Sandbox Code Playgroud)

结果pprint(content):

[{'height': u'600', 'src': u'http://www.detik.com', 'width': u'1000'},
{'height': u'600', 'src': u'http://www.detik.com', 'width': u'1000'},
{'height': u'600', 'src': u'http://www.detik.com', 'width': u'1000'}]
Run Code Online (Sandbox Code Playgroud)

为什么内容的价值不对?它假设与我的值相同print(info).

Bry*_*ley 55

您没有为每个iframe创建单独的字典,您只是反复修改相同的字典,并且不断在列表中添加对该字典的其他引用.

请记住,当您执行类似操作时content.append(info),您不会复制数据,而只是添加对数据的引用.

您需要为每个iframe创建一个新字典.

for iframe in soup.find_all('iframe'):
   info = {}
    ...
Run Code Online (Sandbox Code Playgroud)

更好的是,您不需要先创建一个空字典.只需一次创建它:

for iframe in soup.find_all('iframe'):
    info = {
        "src":    iframe.get('src'),
        "height": iframe.get('height'),
        "width":  iframe.get('width'),
    }
    content.append(info)
Run Code Online (Sandbox Code Playgroud)

还有其他方法可以实现这一点,例如迭代属性列表,或使用列表或字典理解,但很难改进上述代码的清晰度.


Wan*_*ang 36

您误解了Python list对象.它类似于一个C pointer-array.它实际上并不"复制"您附加到它的对象.相反,它只是存储一个指向该对象的"指针".

请尝试以下代码:

>>> d={}
>>> dlist=[]
>>> for i in xrange(0,3):
    d['data']=i
    dlist.append(d)
    print(d)

{'data': 0}
{'data': 1}
{'data': 2}
>>> print(dlist)
[{'data': 2}, {'data': 2}, {'data': 2}]
Run Code Online (Sandbox Code Playgroud)

那么为什么print(dlist)不一样print(d)呢?

以下代码显示了原因:

>>> for i in dlist:
    print "the list item point to object:", id(i)

the list item point to object: 47472232
the list item point to object: 47472232
the list item point to object: 47472232
Run Code Online (Sandbox Code Playgroud)

所以你可以看到它中的所有项目dlist实际上指向同一个dict对象.

这个问题的真正答案是通过使用附加目标项的"副本" d.copy().

>>> dlist=[]
>>> for i in xrange(0,3):
    d['data']=i
    dlist.append(d.copy())
    print(d)

{'data': 0}
{'data': 1}
{'data': 2}
>>> print dlist
[{'data': 0}, {'data': 1}, {'data': 2}]
Run Code Online (Sandbox Code Playgroud)

试试这个id()技巧,你可以看到列表项实际指向完全不同的对象.

>>> for i in dlist:
    print "the list item points to object:", id(i)

the list item points to object: 33861576
the list item points to object: 47472520
the list item points to object: 47458120
Run Code Online (Sandbox Code Playgroud)

  • 我认为`.copy()`只有在你想要复制某些内容时才有意义.虽然同意在某些情况下你可能只想改变一个项目的一部分,但在这个特定问题的情况下,我认为OP显然打算为每个iframe创建一个新的字典,而不是复制和修改.<耸肩> (3认同)
  • 那么...您是在提倡用户使用`.copy()`方法,而不是每次迭代都创建一个新字典?我认为在这种情况下这是错误的。 (2认同)

小智 5

如果你想要一行:

list_of_dict = [{} for i in range(list_len)]
Run Code Online (Sandbox Code Playgroud)