если / еще в понимании списка? - PullRequest
698 голосов
/ 23 ноября 2010

Как я могу сделать следующее в Python?

row = [unicode(x.strip()) for x in row if x is not None else '']

По существу:

  1. заменить все None пустыми строками, а затем
  2. выполнитьфункция.

Ответы [ 8 ]

1063 голосов
/ 23 ноября 2010

Вы можете сделать это полностью, это просто вопрос заказа:

[unicode(x.strip()) if x is not None else '' for x in row]

В общем

[f(x) if condition else g(x) for x in sequence]

И, для списочных представлений только с if условиями,

[f(x) for x in sequence if condition]

Обратите внимание, что на самом деле используется другая языковая конструкция, условное выражение , которое само по себе не является частью синтаксиса понимания , а if после for…in часть списочного понимания и используется для фильтрации элементов из исходного источника.


Условные выражения могут использоваться во всех видах ситуаций, когда вы хотите выбирать между двумя значениями выражений на основе некоторого условия. Это аналогично троичному оператору ?:, существующему в других языках . Например:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')
40 голосов
/ 23 ноября 2010

В одну сторону:

def change(f):
    if f is None:
        return unicode(f.strip())
    else:
        return ''

row = [change(x) for x in row]

Хотя тогда у вас есть:

row = map(change, row)

Или вы можете использовать лямбда-инлайн.

36 голосов
/ 08 октября 2012

Вот еще один иллюстративный пример:

>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!

Используется тот факт, что if i оценивается как False для 0 и True для всех других значений, генерируемых функцией range(). Поэтому понимание списка оценивается следующим образом:

>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']
27 голосов
/ 21 июня 2018

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

Вот пример, который показывает, как условные выражения могут быть записаны в понимании списков:

X = [1.5, 2.3, 4.4, 5.4, 'n', 1.5, 5.1, 'a']     # Original list

# Extract non-strings from X to new list
X_non_str = [el for el in X if not isinstance(el, str)]  # When using only 'if', put 'for' in the beginning

# Change all strings in X to 'b', preserve everything else as is
X_str_changed = ['b' if isinstance(el, str) else el for el in X]  # When using 'if' and 'else', put 'for' in the end

Обратите внимание, что в первом понимании списка для X_non_str порядок:

выражение для item в повторяемость , если условие

и в последнем понимании списка для X_str_changed, порядок:

выражение1 если условие еще выражение2 для элемент в повторяемость

Мне всегда трудно вспомнить, что expresseion1 должно быть до , если и expression2 должно быть после else .Моя голова хочет, чтобы оба были либо до, либо после.

Полагаю, он так устроен, потому что напоминает обычный язык, например: "Я хочу остаться внутри , если дождь, иначе Я хочу выйти на улицу"

4 голосов
/ 14 июля 2018

Другие решения отлично подходят для одной if / else конструкции.Тем не менее, троичные операторы в списках могут быть трудно читаемыми.

Использование функции способствует удобочитаемости, но такое решение сложно расширить или адаптировать в рабочем процессе, где отображение является входным.Словарь может облегчить эти проблемы:

row = [None, 'This', 'is', 'a', 'filler', 'test', 'string', None]

d = {None: '', 'filler': 'manipulated'}

res = [d.get(x, x) for x in row]

print(res)

['', 'This', 'is', 'a', 'manipulated', 'test', 'string', '']
0 голосов
/ 25 июня 2019

«Составить список из элементов в итерации»

Лучше сначала обобщить все возможные формы, чем давать конкретные ответы на вопросы. В противном случае читатель не узнает, как был определен ответ. Вот несколько обобщенных форм, которые я придумал, прежде чем почувствовал головную боль, пытаясь решить, можно ли использовать в последней форме последний оператор else.

[выражение1 (элемент) для элемента в итерируемом]

[выражение1 (элемент), если условие1 для элемента в итерируемом]

[выражение1 (элемент), если условие1, иначе выражение2 (элемент) для элемента в итерируемом]

[expression1 (item), если условное1, иначе выражение2 (item) для элемента в итерируемое, если условное2]

Значение 'item' не нужно использовать ни в одном из условных предложений. «Condition3» может использоваться как переключатель для добавления или не добавления значения в список вывода.

Например, чтобы создать новый список, который исключает пустые строки или строки пробелов из исходного списка строк:

newlist = [s для s в первом списке, если s.strip ()]

0 голосов
/ 08 мая 2019

нет необходимости в троичной системе if / then / else. на мой взгляд ваш вопрос требует этого ответа:

row = [unicode((x or '').strip()) for x in row]
0 голосов
/ 20 марта 2019
# coding=utf-8

def my_function_get_list():
    my_list = [0, 1, 2, 3, 4, 5]

    # You may use map() to convert each item in the list to a string, 
    # and then join them to print my_list

    print("Affichage de my_list [{0}]".format(', '.join(map(str, my_list))))

    return my_list


my_result_list = [
   (
       number_in_my_list + 4,  # Condition is False : append number_in_my_list + 4 in my_result_list
       number_in_my_list * 2  # Condition is True : append number_in_my_list * 2 in my_result_list
   )

   [number_in_my_list % 2 == 0]  # [Condition] If the number in my list is even

   for number_in_my_list in my_function_get_list()  # For each number in my list
]

print("Affichage de my_result_list [{0}]".format(', '.join(map(str, my_result_list))))

(venv) $ python list_comp.py
Affichage de my_list [0, 1, 2, 3, 4, 5]
Affichage de my_result_list [0, 5, 4, 7, 8,9]

Итак, для вас: row = [('', unicode(x.strip()))[x is not None] for x in row]

...