我用下面的方法编写程序

from xml.etree.ElementTree import ET

xmlroot = ET.fromstring([my xml content])

for element in xmlroot.iterfind(".//mytag"):
    do some thing

它在我的python(v2.7.1)上可以正常工作,但是在将它复制到安装有python v2.6.x的另一台计算机上之后,在python document上不支持iterfind(),下面列出了说明



我的问题是:这2个功能是否相同?这两个功能有什么区别

最佳答案

就像文档中指出的那样-

  • findall 返回与match xpath匹配的元素的完整列表,我们可以使用下标访问它们,例如-
    >>> root = ET.fromstring("<a><b>c</b></a>")
    >>> root.findall("./b")
    [<Element 'b' at 0x02048C90>]
    >>> lst = root.findall("./b")
    >>> lst[0]
    <Element 'b' at 0x02048C90>
    

  • 我们还可以使用for循环遍历列表。
  • iterfind 返回一个迭代器(生成器),它不返回列表,在这种情况下,我们不能使用下标来访问元素,我们只能在接受迭代器的地方使用它,例如在for循环中。

  • 如果您实际上要遍历返回的列表(这是我的大部分时间),则iterfind会比findall更快,因为findall必须在返回之前创建完整的列表,而iterfind则查找(产生)下一个元素仅在迭代并调用match时才与next(iter)匹配(这是使用for或此类构造在列表中迭代时内部调用的名称)。

    如果您需要列表,两者似乎都有相似的时间安排。

    两种情况下的性能测试-
    In [1]: import xml.etree.ElementTree as ET
    
    In [2]: x = ET.fromstring('<a><b>c</b><b>d</b><b>e</b></a>')
    
    In [3]: def foo(root):
       ...:     d = root.findall('./b')
       ...:     for  y in d:
       ...:         pass
       ...:
    
    In [4]: def foo1(root):
       ...:     d = root.iterfind('./b')
       ...:     for y in d:
       ...:         pass
       ...:
    
    In [5]: %timeit foo(x)
    100000 loops, best of 3: 9.24 µs per loop
    
    In [6]: %timeit foo1(x)
    100000 loops, best of 3: 6.65 µs per loop
    
    In [7]: def foo2(root):
       ...:     return root.findall('./b')
       ...:
    
    In [8]: def foo3(root):
       ...:     return list(root.iterfind('./b'))
       ...:
    
    In [9]: %timeit foo2(x)
    100000 loops, best of 3: 8.54 µs per loop
    
    In [10]: %timeit foo3(x)
    100000 loops, best of 3: 8.4 µs per loop
    

    10-08 02:47