lxml - minor problem appending new element

Frank Millman frank at chagford.com
Mon Feb 3 04:43:25 EST 2020


On 2020-02-03 10:39 AM, Peter Otten wrote:
> Frank Millman wrote:
> 
>> This is a minor issue, and I have found an ugly workaround, but I
>> thought I would mention it.
> 
> Like this?
> 
> children = list(xml)
> for y in children:
>      print(etree.tostring(y))
>      if y.get('z') == 'c':
>          child = etree.Element('y', attrib={'z': 'd'})
>          xml.append(child)
>          children.append(child)
> 
> It doesn't look /that/ ugly to me.
>   

That is not bad. My actual solution was to revert to the non-pythonic 
method of iterating over a list -

   pos =  0
   while pos < len(xml):
     y = xml[pos]
     print(etree.tostring(y))
     if y.get('z') == 'c':
       xml.append(etree.Element('y', attrib={'z': 'd'}))
     pos += 1

That way, if I append to xml, I automatically pick up the appended element.

>> In Python I can iterate through a list, and on a certain condition
>> append a new item to the list, which is then included in the iteration.
> 
> Personally I follow the rule "never mutate a list you are iterating over",
> even for appends, where the likelihood of problems is small:
> 
> items = ["a"]
> for item in items:
>     if item == "a": items.append("a")
>   

I did feel a bit uneasy doing it, but once I had got it working it did 
not feel too bad. I did not test for appending from the last item, so 
that bug has just bitten me now, but I will run with my workaround 
unless/until lxml is fixed.

>>
>> Is there any chance that this can be looked at, or is it just the way it
>> works?
> 
> File a bug report and see if the author is willing to emulate the list
> behaviour.
>   

Will do.

>> BTW, I see that ElementTree in the standard library does not have this
>> problem.
> 
> Maybe uses a list under the hood.
> 

Thanks for the advice.

Frank


More information about the Python-list mailing list