#python #list #scikit-learn #conditional #list-comprehension
#python #Список #scikit-learn #условное #список-понимание
Вопрос:
Мне было интересно, как превратить следующее в понимание:
for g in a:
for f in g[::3]:
if f == clf.best_params_:
print g
Я попробовал это:
p = [[print g for g in a] if f==clf.best_params for f in [g[::3] for g in a]]
p
но получил ошибку при for f in
Была бы рада некоторой помощи! Спасибо!
Комментарии:
1. Как правило, циклы с побочными эффектами (например, печать) не поддаются пониманию…
2. Вы понимаете, что print возвращает
None
?3. @leaf — похоже, что OP находится на python2.x, где
__future__
импорта).4. @mgilson Стреляй! Я всегда скучаю по этому.
5. Понимание — это способ создания списка, а не просто повторное выполнение действий, для которых цикл for уже является Pythonic =)
Ответ №1:
Правильный способ перевести эти циклы будет
[print g for g in a for f in g[::3] if f == clf.best_params_]
Однако в Python 2 print g
это оператор, и именно поэтому вы получаете SyntaxError . Аналог Python 3 (т. Е. С print(g)
) будет работать, но обратите внимание, что понимание списка здесь совершенно бесполезно. Понимание списка полезно, когда вам нужно собрать значения в список — здесь это просто затрудняет читаемость.
Что касается SyntaxError, это не основная проблема здесь. Обратите внимание, что вы можете использовать
from __future__ import print_function
а затем используйте print()
функцию в вашем понимании списка, как в Python 3.
Комментарии:
1. Спасибо за ваш ответ! Ясность была очень полезной, и было приятно услышать, как сформулирована ошибка синтаксиса печати. Моим намерением было сохранить список, а не печатать, но я случайно оставил инструкцию print при проверке, работает ли цикл.
2. @FlowNuwen Рад, что смог помочь. Если вы намерены сохранить список, то изначально я написал, как вы пишете понимание списка: все циклы for следуют один за другим, а самый внутренний оператор if находится в конце. Обратите внимание, что либо у вас есть один оператор if, либо у вас его нет. У вас не может быть нескольких операторов if в понимании списка.
Ответ №2:
Я думаю, вы перепутали конструкцию: это понимание списка, а не какой-то макрос.
Вы не получаете такого рода побочный эффект; цель понимания списка — создать список.
Комментарии:
1. Однако вы получаете побочные эффекты. Затем список заполняется бесполезными значениями. С другой стороны, я согласен с вами в том, что понимание списка здесь полностью используется неправильно.
2.Вы можете получить побочные эффекты при понимании списка, например. изменение списка, но это очень плохая практика. В этом примере пытается использовать
statement
даже неправильный синтаксис
Ответ №3:
Правило 1 — Сохраняйте порядок частей for
и if
одинаковым. Единственная часть, которая меняет порядок, — это последняя часть print g
:, которая перемещается вперед.
[print g for g in a for f in g[::3] if f == clf.best_params_]
Правило 2 — Понимание списка не должно ничего делать. Вместо печати g
должно g
быть значение, которое накапливается.
[g for g in a for f in g[::3] if f == clf.best_params_]
Если вся ваша цель состояла в том, чтобы просто печатать вещи, придерживайтесь оригинальных циклов; понимание списка не добавит никакой ценности.
Если мы еще раз взглянем на ваши исходные вложенные циклы, возможно, найдется лучший способ их написания. Ваша цель — найти все элементы g
, которые clf.best_params_
находятся в одной из соответствующих позиций? Если это так, я рекомендую заменить внутренний цикл одним if any
оператором.
for g in a:
if any(f == clf.best_params_ for f in g[::3]):
print g
Для меня это читается лучше. Логика понятнее. Он будет печатать любое значение только один g
раз, а не несколько раз, если clf.best_params_
присутствует более одного раза.
Если это улучшение, то вы можете преобразовать эту версию в понимание списка следующим образом:
[g for g in a if any(f == clf.best_params_ for f in g[::3])]
Комментарии:
1. могу ли я запросить источник для этих правил
2. Первый — это просто то, как работает преобразование. Второе — это не столько «правило», сколько лучшая практика. Я отношусь к этому как к правилу: я никогда не пишу понимание списка, которое имеет побочные эффекты.
3. Спасибо! Я не собирался печатать, но я просто вставил его, чтобы проверить, что он работает изначально.