Ответы:
Вы можете сделать это полностью. Это просто вопрос заказа:
[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')
l = [ 2, 3, 4, 5]
то [x if x % 2 == 0 for x in l]
дай мне ошибку, тогда как [x if x % 2 == 0 else 200 for x in l]
работает. Да, я знаю, чтобы отфильтровать это, я должен написать [ x for x in l if x % 2 == 0]
. Извините за беспокойство. Спасибо за Ваш ответ.
В одну сторону:
def change(f):
if f is None:
return unicode(f.strip())
else:
return ''
row = [change(x) for x in row]
Хотя тогда у вас есть
row = map(change, row)
Или вы можете использовать лямбда-инлайн.
if
выражения или кода в его else
блоке операторов или s. Принятый ответ лучше для простых случаев.
Вот еще один иллюстративный пример:
>>> 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']
Конкретная проблема уже была решена в предыдущих ответах, поэтому я остановлюсь на общей идее использования условных выражений в списках.
Вот пример, который показывает, как условные выражения могут быть записаны в понимании списка:
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
, порядок:
выражение для элемента в Iterable , если условие
и в последнем понимании списка X_str_changed
, порядок:
выражение1, если условие еще выражение2 для элемента в итерируемом
Мне всегда трудно вспомнить, что expresseion1 должен быть до, если и expression2 должен быть после else . Моя голова хочет, чтобы оба были либо до, либо после.
Я предполагаю, что это разработано так, потому что это напоминает нормальный язык, например: «Я хочу оставаться внутри, если идет дождь, иначе я хочу выйти на улицу»
В простом английском языке два типа перечисленных выше пониманий списка могут быть сформулированы как:
Только с if
:
извлекать для яблока в box_of_apples, если apple_is_ripe
и с if/else
mark_apple, если apple_is_ripe еще оставьте_it_unmarked для яблока в box_of_apples
Другие решения отлично подходят для одного 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', '']
Это связано с тем, как выполняется понимание списка.
Имейте в виду следующее:
[ expression for item in list if conditional ]
Эквивалентно:
for item in list:
if conditional:
expression
Где expression
в немного другом формате (подумайте о переключении темы и порядка глаголов в предложении).
Следовательно, ваш код [x+1 for x in l if x >= 45]
делает это:
for x in l:
if x >= 45:
x+1
Тем не менее, этот код [x+1 if x >= 45 else x+5 for x in l]
делает это (после перестановки expression
):
for x in l:
if x>=45: x+1
else: x+5
Составьте список из элементов в итерации
Кажется, лучше сначала обобщить все возможные формы, чем давать конкретные ответы на вопросы. В противном случае читатель не узнает, как был определен ответ. Вот несколько обобщенных форм, которые я придумал до того, как у меня заболела голова, пытаясь решить, можно ли использовать последний пункт в последней форме.
[expression1(item) for item in iterable]
[expression1(item) if conditional1 for item in iterable]
[expression1(item) if conditional1 else expression2(item) for item in iterable]
[expression1(item) if conditional1 else expression2(item) for item in iterable if conditional2]
Значение item
не нужно использовать ни в одном из условных предложений. A conditional3
можно использовать как переключатель для добавления или не добавления значения в список вывода.
Например, чтобы создать новый список, который исключает пустые строки или строки пробелов из исходного списка строк:
newlist = [s for s in firstlist if s.strip()]
this if condition else that
разрешено только или нормальное выражение. Нет value = this if condition
(что может быть достигнуто с помощью value = this if condition else None
)
Вы можете комбинировать условную логику в понимании:
ps = PorterStemmer()
stop_words_english = stopwords.words('english')
best = sorted(word_scores.items(), key=lambda x: x[1], reverse=True)[:10000]
bestwords = set([w for w, s in best])
def best_word_feats(words):
return dict([(word, True) for word in words if word in bestwords])
# with stemmer
def best_word_feats_stem(words):
return dict([(ps.stem(word), True) for word in words if word in bestwords])
# with stemmer and not stopwords
def best_word_feats_stem_stop(words):
return dict([(ps.stem(word), True) for word in words if word in bestwords and word not in stop_words_english])
# 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]