首页 > 解决方案 > 出现错误:在 Python 中使用列表理解和条件语句时“没有足够的值来解包”

问题描述

目标是创建一个输出两个值的列表推导。

for 循环如下所示

    paper_href_scopus = []
    paper_title = []
    for litag in all_td.find_all('a', {'class': 'ddmDocTitle'}):
        paper_href_scopus.append(litag['href'])
        paper_title.append(litag.text)

正如OP所建议的,这可以通过

    paper_href_scopus, paper_title = zip(*[(litag['href'], litag.text) for litag in all_td.find_all('a', {'class': 'ddmDocTitle'})])

但是,在某些情况下,all_td.find_all('a', {'class': 'ddmDocTitle'})返回empty并且编​​译器会返回错误:

ValueError:没有足够的值来解包(预期 2,得到 0)

根据this thread中的讨论,上面的代码似乎可以修改为

     paper_href_scopus, paper_title = zip(
                        *((litag['href'], litag.text) for litag in all_td.find_all('a', {'class': 'ddmDocTitle'}) \
                          if all_td.find_all('a', {'class': 'ddmDocTitle'}
                          ))

但是,编译器仍然返回错误

ValueError:没有足够的值来解包(预期 2,得到 0)

尽管如此,以下代码仍然有效,尽管在某些情况下 all_td.find_all('a', {'class': 'ddmDocTitle'})返回empty

    [(paper_href_scopus.append(litag['href']), paper_title.append(litag.text)) \
                     for litag in all_td.find_all('a', {'class': 'ddmDocTitle'})]

paper_href_scopus=[]但是,我想避免使用 append 因为需要 paper_title=[]事先初始化。

我可以知道,我能做些什么来修复代码?

    paper_href_scopus, paper_title = zip(
                        *((litag['href'], litag.text) for litag in all_td.find_all('a', {'class': 'ddmDocTitle'}) \
                          if all_td.find_all('a', {'class': 'ddmDocTitle'}
                          ))

标签: pythonif-statementlist-comprehension

解决方案


首先,带有 的版本if基本等同于:

tmp = []
for litag in all_td.find_all('a', {'class': 'ddmDocTitle'}):
    if all_td.find_all('a', {'class': 'ddmDocTitle'}):
        tmp.append((litag['href'], litag.text))

paper_href_scopus, paper_title = zip(*tmp)

其中,如果您的文档有 100 个匹配元素,它会进行 101 次搜索。

这是我的建议:忘记zip. 相反,将代码拆分一下:

litags = all_td.find_all('a', {'class': 'ddmDocTitle'})
paper_href_scopus = [litag['href'] for litag in litags]
paper_title = [litag.text for litag in litags]

推荐阅读