Python 列表理解中的 if/else

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4260280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:58:23  来源:igfitidea点击:

if/else in a list comprehension

pythonlist-comprehension

提问by AP257

How can I do the following in Python?

如何在 Python 中执行以下操作?

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

Essentially:

本质上:

  1. replace all the Nones with empty strings, and then
  2. carry out a function.
  1. 用空字符串替换所有的无,然后
  2. 执行一项功能。

采纳答案by poke

You can totally do that. It's just an ordering issue:

你完全可以做到这一点。这只是一个订购问题:

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

In general,

一般来说,

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

And, for list comprehensions with ifconditions only,

并且,对于if仅具有条件的列表推导式,

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

Note that this actually uses a different language construct, a conditional expression, which itself is not part of the comprehension syntax, while the ifafter the for…inis part of list comprehensions and used to filterelements from the source iterable.

请注意,这实际上使用了不同的语言结构,即条件表达式,它本身不是推导式语法的一部分,而ifafterfor…in是列表推导式的一部分,用于过滤源迭代中的元素。



Conditional expressions can be used in all kinds of situations where you want to choose between two expression values based on some condition. This does the same as the ternary operator ?:that exists in other languages. For example:

条件表达式可用于您想根据某些条件在两个表达式值之间进行选择的各种情况。这与其他语言中存在三元运算符?:相同。例如:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')

回答by Adam Vandenberg

One way:

单程:

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

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

Although then you have:

虽然那时你有:

row = map(change, row)

Or you can use a lambda inline.

或者您可以使用 lambda 内联。

回答by Bengt

Here is another illustrative example:

这是另一个说明性示例:

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

It exploits the fact that if ievaluates to Falsefor 0and to Truefor all other values generated by the function range(). Therefore the list comprehension evaluates as follows:

它利用了这样的事实if i计算结果为False0True所有其它值由函数生成的range()。因此,列表推导式评估如下:

>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']

回答by Tim Skov Jacobsen

The specific problem has already been solved in previous answers, so I will address the general idea of using conditionals inside list comprehensions.

具体问题已在之前的答案中解决,因此我将介绍在列表推导式中使用条件的一般想法。

Here is an example that shows how conditionals can be written inside a list comprehension:

下面是一个示例,展示了如何在列表推导式中写入条件:

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

Note that in the first list comprehension for X_non_str, the order is:

请注意,在第一个列表推导式中X_non_str,顺序是:

expressionforiteminiterableifcondition

表达项目迭代如果条件

and in the last list comprehension for X_str_changed, the order is:

在最后一个列表理解中X_str_changed,顺序是:

expression1ifconditionelseexpression2foriteminiterable

expression1 if condition else expression2 for item in iterable

I always find it hard to remember that expresseion1has to be before ifand expression2has to be after else. My head wants both to be either before or after.

我总是觉得很难记住expresseion1必须是之前,如果表达式2必须是经过别人。我的头脑希望两者都在之前或之后。

I guess it is designed like that because it resembles normal language, e.g. "I want to stay inside ifit rains, elseI want to go outside"

我想它的设计一样,因为它类似于正常的语言,例如:“我想留在里面,如果下雨,否则我要到外面去”

In plain Englishthe two types of list comprehensions mentioned above could be stated as:

用简单的英语,上面提到的两种列表推导式可以表示为:

With only if:

只有if

extract_appleforappleinbox_of_applesifapple_is_ripe

extract_apple苹果box_of_apples如果apple_is_ripe

and with if/else

if/else

mark_appleifapple_is_ripeelseleave_it_unmarkedforappleinbox_of_apples

mark_apple if apple_is_ripe else leave_it_unmarked for apple in box_of_apples

回答by jpp

The other solutions are great for a single if/ elseconstruct. However, ternary statements within list comprehensions are arguably difficult to read.

其他解决方案非常适合单个if/else构造。然而,列表推导式中的三元语句可能难以阅读。

Using a function aids readability, but such a solution is difficult to extend or adapt in a workflow where the mapping is an input. A dictionary can alleviate these concerns:

使用函数有助于提高可读性,但在映射是输入的工作流中,这种解决方案很难扩展或适应。字典可以减轻这些顾虑:

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', '']

回答by Trop Freshlo?c

# 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]

(venv) $ python list_comp.py 我的
列表[0, 1, 2, 3, 4, 5] 的
地址[0, 5, 4, 7, 8, 9]

So, for you: row = [('', unicode(x.strip()))[x is not None] for x in row]

所以,对你来说: row = [('', unicode(x.strip()))[x is not None] for x in row]

回答by mariotomo

There isn't any need for ternary if/then/else. In my opinion your question calls for this answer:

不需要三元 if/then/else。在我看来,你的问题需要这个答案:

row = [unicode((x or '').strip()) for x in row]

回答by Hewey Dewey

Make a list from items in an iterable

从可迭代的项目中创建一个列表

It seems best to first generalize all the possible forms rather than giving specific answers to questions. Otherwise, the reader won't know how the answer was determined. Here are a few generalized forms I thought up before I got a headache trying to decide if a final else' clause could be used in the last form.

似乎最好首先概括所有可能的形式,而不是对问题给出具体的答案。否则,读者将不知道答案是如何确定的。在我头疼地决定是否可以在最后一种形式中使用最后的 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]

The value of itemdoesn't need to be used in any of the conditional clauses. A conditional3can be used as a switch to either add or not add a value to the output list.

的值item不需要在任何条件子句中使用。Aconditional3可用作向输出列表添加或不添加值的开关。

For example, to create a new list that eliminates empty strings or whitespace strings from the original list of strings:

例如,要创建一个从原始字符串列表中消除空字符串或空白字符串的新列表:

newlist = [s for s in firstlist if s.strip()]

回答by arboc7

It has to do with how the list comprehension is performed.

它与列表理解的执行方式有关。

Keep in mind the following:

请记住以下几点:

[ expression for item in list if conditional ]

Is equivalent to:

相当于:

for item in list:
    if conditional:
        expression

Where the expressionis in a slightly different format (think switching the subject and verb order in a sentence).

其中 the 的expression格式略有不同(想想在句子中切换主语和动词顺序)。

Therefore, your code [x+1 for x in l if x >= 45]does this:

因此,您的代码[x+1 for x in l if x >= 45]执行以下操作:

for x in l:
    if x >= 45:
        x+1

However, this code [x+1 if x >= 45 else x+5 for x in l]does this (after rearranging the expression):

但是,此代码[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

回答by Max Kleiner

You can combine conditional logic in a comprehension:

您可以在理解中组合条件逻辑:

 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])