Список / Условное понимание в Python

#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, где print это оператор (конечно, за исключением __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.Вы можете получить побочные эффекты при понимании списка, например. изменение списка, но это очень плохая практика. В этом примере пытается использовать print 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. Спасибо! Я не собирался печатать, но я просто вставил его, чтобы проверить, что он работает изначально.