2012-07-15 22 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) का परिणाम:

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

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

क्यों सामग्री के मूल्य सही नहीं है? ऐसा लगता है कि जब मैं print(info) पर मान के समान होना चाहिए।

उत्तर

43

आप प्रत्येक आइफ्रेम के लिए एक अलग शब्दकोश रचना नहीं करते हैं, तो आप सिर्फ पर एक ही शब्दकोश संशोधित रखने के लिए, और आप अतिरिक्त जोड़ने रखना आपकी सूची में उस शब्दकोश के संदर्भ।

याद रखें, जब आप content.append(info) जैसे कुछ करते हैं, तो आप डेटा की एक प्रति नहीं बना रहे हैं, आप बस डेटा का संदर्भ जोड़ रहे हैं।

आपको प्रत्येक आईफ्रेम के लिए एक नया शब्दकोश बनाने की आवश्यकता है।

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) 

ऐसे-बार दोहराना के रूप में विशेषताओं, या सूची या शब्दकोश comprehensions का उपयोग कर की एक सूची से अधिक अन्य तरीकों से यह पूरा करने, कर रहे हैं, लेकिन यह ऊपर कोड की स्पष्टता में सुधार करना मुश्किल है ।

+0

संक्षिप्त विवरण के लिए धन्यवाद, यह मेरी पहली अजगर का उपयोग कर कोड है। त्वरित प्रतिक्रिया – l1th1um

2

info एक शब्दकोश के लिए एक सूचक है - आप अपनी सूची contact पर एक ही सूचक जोड़ते रहेंगे।

सम्मिलित लूप में info = {} और यह समस्या का समाधान करना चाहिए:

... 
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

आपने पाइथन list ऑब्जेक्ट को गलत समझा है। यह सी 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(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 

तो तुम 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()' केवल तभी समझ में आता है जब आप वास्तव में कुछ कॉपी करना चाहते हैं। हालांकि इस बात से सहमत है कि कुछ मामलों में यो उमे इस आइटम के केवल एक हिस्से को बदलना चाहते हैं, इस विशेष प्रश्न के मामले में मुझे लगता है कि ओपी स्पष्ट रूप से कॉपी और संशोधित करने के बजाय प्रत्येक आईफ्रेम के लिए एक नया शब्दकोश बनाने का इरादा रख रहा था।

3

आप एक पंक्ति चाहते हैं: डी:

list_of_dict = [{} for i in range(list_len)] 
संबंधित मुद्दे