2012-07-15 6 views
20

웹 페이지에서 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) 

결과 print(info)의 : pprint(content)

{'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'} 

결과 :

[{'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'}] 

왜 컨텐츠의 가치를 잘 작성하지 못했습니다입니까? 내가 print(info) 일 때의 값과 같다고 가정합니다.

답변

43

, 당신은 단지 반복해서 같은 사전을 수정 유지하고, 당신은 추가로 계속 추가 목록에있는 해당 사전에 대한 참조.

content.append(info)과 같은 작업을 수행 할 때 데이터 복사본을 만들지 않고 단순히 데이터에 대한 참조를 추가하는 것입니다.

각 iframe에 대해 새 사전을 만들어야합니다.

for iframe in soup.find_all('iframe'): 
    info = {} 
    ... 

빈 사전을 먼저 만들 필요가 없습니다. 그냥 한 번에 모든 것을 만들 :

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

이 같은 속성, 또는 목록 또는 사전 함축을 사용하여 목록을 반복으로이 작업을 수행 할 수있는 다른 방법이 있습니다,하지만 위의 코드의 명확성을 개선하기 어렵다 .

+0

감사합니다, 이것은 파이썬을 사용하여 내 첫 번째 코드입니다. 또한 빠른 응답을 주셔서 감사합니다 – l1th1um

2

info은 사전에 대한 포인터입니다. contact과 같은 포인터를 계속 추가합니다.

루프에

삽입 info = {}하고 문제를 해결해야한다 : 각 iframe을위한 별도의 사전을 생성하지 않는

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

당신은 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}] 

print(d)과 동일하지 print(dlist)입니다 :

다음 코드를 시도?
>>> 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 

그래서 당신이 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}] 

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 
+1

... 사용자가 매 반복마다 새 사전을 만드는 대신'.copy()'메서드를 사용하도록 권장하고 있습니까? 나는이 특별한 경우에 그것이 잘못되었다고 생각한다. –

+0

많은 경우에, 당신은 단지 항목의 일부분 만 변경할 수 있습니다. 성능 및 의의 측면에서 나는'.copy()'를 선호합니다. 교육면에서'.copy()'는 또한 더 명확한 개념을 제공한다. – Wang

+2

'.copy()'는 실제로 무언가를 복사하고자 할 때만 의미가 있다고 생각합니다. 어떤 경우 엔 어쨌든 항목의 일부만 바꾸고 싶다는 것에 동의하지만,이 특정 질문의 경우 OP는 분명히 복사 및 수정하기보다는 각 iframe에 대한 새 사전을 만들려고합니다.

3

는 : D : 간단한 설명은

list_of_dict = [{} for i in range(list_len)]