Понимание нескольких списков Python не работает, как это сделать правильно? - PullRequest
1 голос
/ 14 октября 2019

Я пытаюсь это:

tmp = "one ; 1 \n two ; 2 \n three ; 3"
choices = [(x.strip(), y.strip()) 
           for choice in tmp.split("\n") 
           for x,y in choice.split(";")
           if choice.find(";") != -1]

Я получаю следующее сообщение об ошибке: {ValueError} too many values to unpack (expected 2). Что я не понимаю. Если я изменю понимание следующим образом:

>>> choices = [x 
               for choice in tmp.split("\n") 
               for x in choice.split(";")]
>>> choices
['one ', ' 1 ', ' two ', ' 2 ', ' three ', ' 3']

Я вижу, что разделение выполняется правильно, но не назначено.

В основном я хочу это:

>>> choices = [magical list comp using tmp variable]
>>> choices
[("one", "1"), ("two", "2"), ...etc ]

Кто-нибудь знает как?!

Ответы [ 3 ]

3 голосов
/ 14 октября 2019

Вы можете сделать следующее:

choices = [tuple(map(str.strip, choice.split(";"))) for choice in tmp.split("\n") if choice.find(";")]
print(choices)

Вывод

[('one', '1'), ('two', '2'), ('three', '3')]
2 голосов
/ 14 октября 2019

Другой ответ дает альтернативное решение, но я упомяну, что проблема в том, что

for x,y in choice.split(";")

повторяет результаты, возвращаемые choice.split(";").

Обратите внимание, что есть разницамежду

for t in choice.split(";")  # t is each element of the list returned by split

и

t = choice.split(";")  # t is the whole list returned by split

Будет понятнее, если вы немного измените понимание, чтобы получить некоторую отладочную информацию:

>>> choices = [(t, len(t))
               for choice in tmp.split("\n") 
               for t in choice.split(";")]

>>> choices
[('one ', 4), (' 1 ', 3), (' two ', 5), (' 2 ', 3), (' three ', 7), (' 3', 2)]

Другое решение будетиспользовать выражения присваивания :

choices = [(x, y := choice.split(";"), (x.strip(), y.strip()))[1] 
           for choice in tmp.split("\n")
           if choice.find(";") != -1]

Не проверено, поскольку это работает только в 3.8, а у меня нет интерпретатора 3.8. Это должно работать, хотя.

Не делайте этого, хотя. Я показываю это только потому, что думаю, что это было то, что вы имели в виду, когда писали for x,y in choice.split(";").

2 голосов
/ 14 октября 2019

Проблема с вашим кодом в том, что вы перебираете строки, но пытаетесь распаковать каждую строку как кортеж из двух элементов.

давайте рассмотрим самую первую итерацию вашего вложенного цикла:

for choice in tmp.split("\n")

приводит к ['one;1 ']

и choice.split(";")

приводит к [' one ']

, поэтому строка for x,y in choice.split(";") будет оценена как x,y='one ' в первой итерации ипотерпит неудачу с ValueError

как насчет:

choices = []

for choice in tmp.split("\n"):
    choices.append(tuple([val.strip() for val in choice.split(";")]))

print(choices)
...