Если / еще в понимании списка Python?
Как я могу сделать следующее в Python?
row = [unicode(x.strip()) for x in row if x is not None else '']
По существу:
- заменить все Nones пустыми строками, а затем
- выполнять функцию.
12 ответов
Вы можете сделать это полностью, это просто вопрос заказа:
[ unicode(x.strip()) if x is not None else '' for x in row ]
Обратите внимание, что здесь фактически используется другая языковая конструкция, условное выражение, которое само по себе не является частью синтаксиса понимания, в то время как if
после for…in
является частью понимания списка и используется для фильтрации элементов из итерируемого источника.
Условные выражения могут использоваться во всех видах ситуаций, когда вы хотите выбирать между двумя значениями выражений на основе некоторого условия. Это так же, как троичный оператор ?:
что существует на других языках. Например:
value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')
Давайте воспользуемся этим вопросом, чтобы рассмотреть некоторые концепции. Я думаю, что хорошо сначала увидеть основы, чтобы вы могли экстраполировать их на разные случаи.
Другие ответы дают конкретный ответ на ваш вопрос. Сначала я дам общий контекст, а затем отвечу на вопрос.
Основы
if/else
Операторы в понимании списков включают в себя две вещи:
- Составить список
- Условные выражения (тернарные операторы)
1. Составьте список понятий
Они обеспечивают лаконичный способ создания списков.
Его структура состоит из: « скобок, содержащих выражение, за которым следует предложение for, затем ноль или более предложений for или if ».
Дело 1
Здесь у нас нет условий. Каждый элемент из итерируемого добавляется в.
new_list = [expression for item in iterable]
new_list = [x for x in range(1, 10)]
> [1, 2, 3, 4, 5, 6, 7, 8, 9]
Случай 2
Здесь у нас есть одно условие.
Пример 1
Условие: будут добавляться только четные числа.
new_list = [expression for item in iterable if condition == True]
new_list = [x for x in range(1, 10) if x % 2 == 0]
> [2, 4, 6, 8]
Пример 2
Условие: будут добавляться только четные числа, кратные 3.
new_list = [expression for item in iterable if condition == True]
new_list = [x for x in range(1, 10) if x % 2 == 0 if x % 3 == 0]
> [6]
Но откуда у нас одно условие, если мы используем два?
Предыдущее выражение можно было бы записать как:
new_list = [x for x in range(1, 10) if x % 2 and x % 3 == 0]
> [6]
Мы используем только один
if
утверждение.
Это похоже на выполнение:
new_list = []
for x in range(1, 10):
if x % 2 == 0 and x % 3 == 0:
new_list.append(x)
> [6]
Пример 3
Просто для аргументации вы также можете использовать
or
.
Условие: четные числа или числа, кратные 3, будут добавлены к
new_list
.
new_list = [x for x in range(1, 10) if x % 2 == 0 or x % 3 == 0]
> [2, 3, 4, 6, 8, 9]
Случай 2
Более одного условия:
Здесь нам понадобится помощь условных выражений (тернарных операторов).
2. условные выражения
Что такое условные выражения? Что говорит название: выражение Python с некоторым условием.
<Exp1> if condition else <Exp2>
Сначала оценивается. Если есть
True
, тогда
<Exp1>
оценивается и возвращается. Если
condition
является
False
, тогда
<Exp2>
оценивается и возвращается.
Условное выражение с более чем одним условием:
<Exp1> if condition else <Exp2> if condition else <Exp3>...
Пример из Real Python:
age = 12
s = 'minor' if age < 21 else 'adult'
> minor
Значение
s
обусловлено
age
ценить.
3. Составьте список выражений с помощью условных выражений
Мы объединяем понимание списков и условные выражения следующим образом.
new_list = [<Conditional Expression> for <item> in <iterable>]
new_list = [<Exp1> if condition else <Exp2> if condition else <Exp3> for <item> in <iterable>]
Условие: четные числа будут добавлены как
'even'
, число три будет добавлено как
'number three'
а остальные будут добавлены как
'odd'
.
new_list = ['even' if x % 2 == 0 else 'number three' if x == 3 else 'odd'
for x in range(1, 10)]
> ['odd', 'even', 'number three', 'even', 'odd', 'even', 'odd', 'even', 'odd']
Ответ на вопрос
row = [unicode(x.strip()) for x in row if x is not None else '']
Здесь у нас проблема со структурой списка:
for x in row
должен быть в конце выражения.
Правильный способ:
new_row = [unicode(x.strip()) if x is not None else '' for x in row]
Дальнейшее чтение:
Конкретная проблема уже была решена в предыдущих ответах, поэтому я остановлюсь на общей идее использования условных выражений в списках.
Вот пример, который показывает, как условные выражения могут быть записаны в понимании списка:
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
заказ:
значение для expression1, если expression2
и в последнем списке понимания для X_str_changed
заказ:
значение1, если выражение1 еще значение2 для выражения2
Мне всегда трудно помнить, что значение1 должно быть раньше, если значение 2 должно быть после другого. Моя голова хочет, чтобы оба были либо до, либо после.
Я предполагаю, что это разработано так, потому что это напоминает нормальный язык, например: "Я хочу оставаться внутри, если идет дождь, иначе я хочу выйти на улицу"
В одну сторону:
def change(f):
if f is None:
return unicode(f.strip())
else:
return ''
row = [change(x) for x in row]
Хотя тогда у вас есть:
row = map(change, row)
Или вы можете использовать лямбда-инлайн.
Вот еще один иллюстративный пример:
>>> 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']
Ты можешь это сделать
row = [unicode(x.strip()) if x != None else '' for x in row]
Некоторый синтаксис для понимания списка:
[item if condition else item for item in items]
[f(item) if condition else value for item in items]
[item if condition for item in items]
[value if condition else value1 if condition1 else value2]
Другие решения отлично подходят для одного 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
Составьте список из элементов в повторяемом
Лучше сначала обобщить все возможные формы, чем давать конкретные ответы на вопросы. Иначе читатель не узнает, как был определен ответ. Вот несколько обобщенных форм, которые я придумал до того, как у меня заболела голова, пытаясь решить, можно ли использовать последнее предложение else в последней форме.
[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
не нужно использовать ни в одном из условных предложений. Аconditional3
может использоваться как переключатель для добавления или не добавления значения в список вывода.
Например, чтобы создать новый список, который удаляет пустые строки или строки с пробелами из исходного списка строк:
newlist = [s for s in firstlist if s.strip()]
Вы можете комбинировать условную логику в понимании:
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])
Нет необходимости в тернарном if/then/else. На мой взгляд, ваш вопрос требует такого ответа:
row = [unicode((x or '').strip()) for x in row]
# 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
Информация о my_list [0, 1, 2, 3, 4, 5]
Информация о my_result_list [0, 5, 4, 7, 8, 9]
Итак, для вас:row = [('', unicode(x.strip()))[x is not None] for x in row]