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+y
与 x+=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>]
我想查找一个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+y
与 x+=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>]