2015-07-20 26 views
2

我想知道爲什麼在此代碼append()似乎從循環內部工作,但生成的xml顯示修改只從最後一次迭代,而remove()按預期工作。這是一個過分簡化的例子,我正在處理大量的數據,並且需要將相同的子樹附加到許多不同的父母身上。從循環lxml.etree._Element.append()不按預期工作

from lxml import etree 

xml = etree.fromstring('<tree><fruit id="1"></fruit><fruit id="2"></fruit></tree>') 
sub = etree.fromstring('<apple/>') 

for i, item in enumerate(xml): 
    item.append(sub) 
    print('Fruit {} with sub appended: {}'.format(
     i, etree.tostring(item).decode('ascii'))) 

print('\nResulting tree after iterating through items with append():\n' + 
    etree.tostring(xml, pretty_print=True).decode('ascii')) 

for item in xml: 
    xml.remove(item) 

print('Resulting tree after iterating through items with remove():\n' + 
    etree.tostring(xml, pretty_print=True).decode('ascii')) 

電流輸出:

Fruit 0 with sub appended: <fruit id="1"><apple/></fruit> 
Fruit 1 with sub appended: <fruit id="2"><apple/></fruit> 

Resulting tree after iterating through items with append(): 
<tree> 
    <fruit id="1"/> 
    <fruit id="2"> 
    <apple/> 
    </fruit> 
</tree> 

Resulting tree after iterating through items with remove(): 
<tree/> 
通過項目與append()迭代後

預期輸出:

<tree> 
    <fruit id="1"/> 
    <apple/> 
    </fruit> 
    <fruit id="2"> 
    <apple/> 
    </fruit> 
</tree> 

回答

1

那是因爲你只創建了一個實例被附加的<apple/> 。所以基本上你只是將一個實例從一個父母移到另一個父母,直到最後一個append(sub)執行完畢。嘗試for環路內移動<apple/>元素的創作,而不是:

for i, item in enumerate(xml): 
    sub = etree.fromstring('<apple/>') 
    item.append(sub) 
    print('Fruit {} with sub appended: {}'.format(
     i, etree.tostring(item).decode('ascii'))) 
print() 

輸出:

Resulting tree after iterating through items with append(): 
<tree> 
    <fruit id="1"> 
    <apple/> 
    </fruit> 
    <fruit id="2"> 
    <apple/> 
    </fruit> 
</tree> 
+0

這樣的作品,謝謝!爲什麼'print('Fruit {}帶有子追加:{}'...'打印正確的輸出?我是python的新手,所以這是一些概念,我還不明白! –

+1

好吧,它實際上是修改過的每個項目,但後來''後來被刪除,現在我想我明白了!謝謝! –

+0

你去了!:)不客氣 – har07