python 递归列表

python list in Recursion

我想查找一个div中的所有链接,例如:

<div>
  <a href="#0"></a>
  <a href="#1"></a>
  <a href="#2"></a>
</div>

所以我写了一个函数如下:

def get_links(div):
    links = []
    if div.tag == 'a':
        links.append(div)
        return links   
    else:
        for a in div:
            links + get_links(a)
        return links

为什么结果是[]而不是[a, a, a]? ------ 问题

我知道这是一个list reference的问题,能不能详细说一下

这是完整的模块:

import lxml.html


def get_links(div):
    links = []
    if div.tag == 'a':
        links.append(div)
        return links   
    else:
        for a in div:
            links + get_links(a)
        return links


if __name__ == '__main__':

    fragment = '''
        <div>
          <a href="#0">1</a>
          <a href="#1">2</a>
          <a href="#2">3</a>
        </div>'''
    fragment = lxml.html.fromstring(fragment)
    links = get_links(fragment)    # <---------------

在 Python 中添加列表 returns 从参数的串联中获得的新列表,不会更改它们:

x = [1, 2, 3, 4]
print(x + [5, 6])  # displays [1, 2, 3, 4, 5, 6]
print(x)           # here x is still [1, 2, 3, 4]

你可以使用extend方法:

x.extend([5, 6])

+=

x += [5, 6]

后者有点像 IMO "strange",因为在这种情况下 x=x+yx+=y 不同,因此我更愿意避免它并就地制作扩展更明确。

为您的代码

links = links + get_links(a)

也是可以接受的,但请记住它做了不同的事情:它分配了一个带有串联的新列表,然后分配名称 links 以指向它:它不会更改引用的原始对象通过 links:

x = [1, 2, 3, 4]
y = x
x = x + [5, 6]
print(x)   # displays [1, 2, 3, 4, 5, 6]
print(y)   # displays [1, 2, 3, 4]

但是

x = [1, 2, 3, 4]
y = x
x += [5, 6]
print(x)   # displays [1, 2, 3, 4, 5, 6]
print(y)   # displays [1, 2, 3, 4, 5, 6]

如果标签不是 'a' 你的代码看起来像那样。

# You create an empty list

links = []
for a in div:
    # You combine <links> with result of get_links() but you do not assign it to anything
    links + get_links(a)
# So you return an empty list   
return links

您应该将 + 更改为 +=:

links += get_links(a)

或使用extend()

links.extend(get_links(a))

其他选项是使用 xpath 方法从 div 的任何级别获取所有 a 标签。

代码:

from lxml import etree
root = etree.fromstring(content)
print root.xpath('//div//a')

输出:

[<Element a at 0xb6cef0cc>, <Element a at 0xb6cef0f4>, <Element a at 0xb6cef11c>]