#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:
Сначала несколько заметок для вашего исходного кода:
-
Вместо
if str(item).isdigit() != True:
используйте больше Pythonic
if not str(item).isdigit():
-
Вместо того, чтобы использовать тот же умозрительный способ достижения вашей цели, используйте более понятный
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. Ваша точность описания разъяснений в этом факте была невероятной. Спасибо за помощь, приятель!