Получение ошибки: «недостаточно значений для распаковки» при использовании понимания списка вместе с условным оператором в Python - PullRequest
2 голосов
/ 01 августа 2020

Цель состоит в том, чтобы создать понимание списка, которое выводит два значения.

Циклы 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)

Основываясь на обсуждении в этой ветке , кажется, что приведенный выше код можно изменить как

     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'})]

Но я бы не хотел использовать append, так как требуется заранее инициализировать paper_href_scopus=[] и 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'}
                          ))

1 Ответ

1 голос
/ 01 августа 2020

Во-первых, версия с 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]
...