если еще в понимании списка с помощью цикла for

#python #python-3.x #list

#python #python-3.x #Список

Вопрос:

Я написал свое собственное простое решение для сглаживания списка:

 lists = [0, 10, [20, 30], 40, 50, [60, 70, 80], [90, 100, 110, 120]]
new = []
for item in lists:
    if str(item).isdigit() != True:
        for v in item:
            new.append(v)
    else:
        new.append(item)
print(new)
  

Но я хочу добавить else / elif к следующему коду, чтобы сделать код короче:

 new = [v for item in lists if str(item).isdigit() != True for v in item]
  

Я не знаю, как получить синтаксические ошибки.

Ответ №1:

Попробуйте это:

 >>> [v for item in lists for v in (item if isinstance(item, list) else [item])]
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120]
  

Это немного неэффективно, поскольку оно переносит целое число в список, а затем повторяет его, но это не должно иметь значения для большинства целей. Старайтесь не использовать строковые представления для проверки типов данных, так как вы можете получить неожиданные результаты (например, попробуйте запустить исходный код с плавающей точкой вместо целого числа в списке).

Комментарии:

1. для полноты картины я бы упомянул: collections.abc.Iterable

2. @Aaron Честно говоря, это было похоже на слишком большую работу, поскольку она также ненадежна. Вызов iter и перехват исключений — это правильный путь, но это усложнило бы этот пример и упустило бы суть.

3. В соответствии с вашим решением я нашел свое новое, ха-ха.. спасибо, приятель 🙂 new = [v for item in lists for v in (item if str(item).isdigit() != True else [item])]

Ответ №2:

Сначала несколько заметок для вашего исходного кода:

  1. Вместо

     if str(item).isdigit() != True:
      

    используйте больше Pythonic

     if not str(item).isdigit():
      
  2. Вместо того, чтобы использовать тот же умозрительный способ достижения вашей цели, используйте более понятный

     if type(item) is not list:
      

Теперь о else понимании списка. Это может быть только в первой его части, синтаксис понимания списка не допускает этого после for предложения (в if выражениях фильтрации).

Итак, вам нужно изменить итерируемый во втором for вашем понимании списка, чтобы он всегда был итерируемым, т. Е., Например, для item

  • [20, 30] это нормально (потому что это итерируемый)
  • 10 это не нормально (потому что это не итерируемый) — так что давайте заключим его в скобки — [10]

Итак, мы будем переключаться между item и [item] в зависимости от type(item) :

  item     if type(item) is list     else     [item]
  

(Это условное выражение, а не понимание списка, так else что здесь все в порядке.)

Таким образом, полное решение может быть

 new = [v for item in lists 
         for v in (item if type(item) is list else [item])]
  

Комментарии:

1. Ваша точность описания разъяснений в этом факте была невероятной. Спасибо за помощь, приятель!