列表推导中的 if/else
- 2024-11-21 08:33:00
- admin 原创
- 6
问题描述:
如何将以下for
包含if
/ 的-loop 转换else
为列表推导?
results = []
for x in xs:
results.append(f(x) if x is not None else '')
''
如果x
是 则应该输出None
否则输出f(x)
。我试过了:
[f(x) for x in xs if x is not None else '']
但它给出了一个SyntaxError
。正确的语法是什么?
有关 的信息,请参阅Python 是否有三元条件运算符?... if ... else ...
。有关 的信息
,请参阅带条件的列表推导式以根据条件省略值:。[... for x in xs if x cond]
有关的信息,
请参阅列表推导式条件中的 elif
`elif`。
解决方案 1:
你完全可以这么做。这只是一个顺序问题:
[f(x) if x is not None else '' for x in xs]
一般来说,
[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')
解决方案 2:
让我们用这个问题来回顾一些概念。我认为最好先了解一下基础知识,这样你就可以推断出不同的情况。
其他答案提供了对你的问题的具体答案。我将首先提供一些一般背景,然后再回答问题。
基本面
if/else
列表推导中的语句涉及两件事:
列表推导
条件表达式(三元运算符)
列表推导
它们提供了一种创建列表的简洁方法。
其结构包括:“包含表达式的括号,后跟 for 子句,然后是零个或多个 for 或 if 子句”。
案例 1
这里没有条件。可迭代对象中的每个项目都添加到new_list
。
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
。
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
。
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]
if
但是如果我们使用两个,怎么会有一个条件呢new_list
?
先前的表达式可以写成:
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]
案例 3
多个条件:
这里我们需要条件表达式(三元运算符)的帮助。
2.条件表达式
什么是条件表达式?顾名思义:具有某些条件的 Python 表达式。
<Exp1> if condition else <Exp2>
首先condition
评估。如果condition
是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
价值决定的。
带条件的列表推导
我们把列表推导和条件像这样放在一起。
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']
问题的答案
[f(x) for x in xs if x is not None else '']
这里我们遇到了列表结构的问题:for x in xs
应该位于表达式的末尾。
正确做法:
[f(x) if x is not None else '' for x in xs]
进一步阅读:
Python 有三元条件运算符吗?
解决方案 3:
这个具体问题已经在之前的答案中解决过了,所以我将讨论在列表推导中使用条件的一般思想。
以下示例显示了如何在列表推导式中编写条件语句:
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
,顺序是:
可迭代if条件中的* 项 表达式*
在 的最后一个列表推导中X_str_changed
,顺序为:
表达式1 if 条件 else 表达式2 for item in itable
我总是很难记住表达式1必须位于if之前,而表达式2必须位于else之后。我的大脑希望两者都位于之前或之后。
我猜它之所以这样设计是因为它类似于正常语言,例如“如果下雨我想呆在室内,否则我想出去”
用简单的英语来说,上面提到的两种列表推导式可以表述如下:
仅包含if
:
如果apple_is_ripe,则对 apple_box中的苹果进行 extract_apple
以及if/else
如果 apple_is_ripe则 mark_apple否则如果 apple_box中的苹果则*leave_it_unmarked*
解决方案 4:
单程:
def change(x):
if x is None:
return f(x)
else:
return ''
result = [change(x) for x in xs]
尽管你有:
result = map(change, xs)
或者您可以使用内联 lambda。
解决方案 5:
下面是另一个示例:
>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!
它利用了这样一个事实:对于if i
, 求值为;对于 ,对于函数 生成的所有其他值 ,求值为 。因此,列表推导式求值如下:False
`0True
range()`
>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']
解决方案 6:
[f(x) if x != None else '' for x in xs]
列表理解的语法:
[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]
解决方案 7:
if
其他解决方案对于单个/构造来说非常棒else
。但是,列表推导中的三元语句可能难以阅读。
使用函数有助于提高可读性,但这种解决方案在将映射作为输入的工作流中很难扩展或调整。字典可以缓解这些问题:
xs = [None, 'This', 'is', 'a', 'filler', 'test', 'string', None]
d = {None: '', 'filler': 'manipulated'}
res = [d.get(x, x) for x in xs]
print(res)
['', 'This', 'is', 'a', 'manipulated', 'test', 'string', '']
解决方案 8:
这与列表理解的执行方式有关。
请记住以下几点:
[ 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
解决方案 9:
根据可迭代对象中的项目创建列表
最好先概括所有可能的形式,而不是给出问题的具体答案。否则,读者将不知道答案是如何确定的。以下是我在为决定最后一个形式中是否可以使用最后一个 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
不需要在任何条件子句中使用。Aconditional3
可以用作开关,用于选择向输出列表添加或不添加值。
例如,要创建一个新列表,从原始字符串列表中消除空字符串或空格字符串:
newlist = [s for s in firstlist if s.strip()]
解决方案 10:
其他答案解释得很好,但我只是想补充一些关于在列表理解中使用哪个条件表达式的信息。
正如文档所述,列表推导式用于通过 for 循环创建列表,其一般结构如下:
[expression for item in iterable (0 or more if/for clauses)]
它可以创建:
expression
通过迭代计算列表,或者iterable
如果if
语句遵循初始for
语句,则产生子序列
从上面的一般结构中,我们可以看出,else
语句不能跟在for
语句后面;for
但可以跟在if
虽然后面;因此以下是有效的代码:
[y for x in range(5) if x % 2 == 0 for y in range(x)]
因此,任何 if-else 控制流都必须在上面的评估中完成expression
。此外,由于列表推导会创建一个列表,因此expression
必须是可以分配给变量的表达式。因此,诸如 bare 之类的条件表达式if
无法工作,因为我们不知道如果条件不为 True,值应该是什么。它类似于如何将变量定义x
为x = 10 if True
SyntaxError。因此,如果expression
包含条件语句,它必须包含else
,类似于x = 10 if True else 5
可以定义变量x
。
总而言之,使用 if/else 应被视为上述情况 (1) 的特殊情况,其中expression
在迭代中进行评估,但要注意expression
包含一个条件,如下所示:
[(expression1 if condition else expression2) for item in iterable]
列表推导式中一个
if
语句跟在另一个for
语句后面(上面的情况 (2))类似于用数学符号从给定集合中定义一个子集,因此[x for x in iterable if m<x<n]
类似于{x ∈ iterable | m<x<n}
。由于列表推导会创建一个列表,如果创建列表不是目的,就不应该使用它;它不应该简单地用来编写一行 for 循环;所以不要写
[print(x) for x in range(5)]
例如。
解决方案 11:
没有必要使用三元 if/then/else。我认为您的问题需要这样的答案:
row = [unicode((x or '').strip()) for x in row]
解决方案 12:
您可以在理解中组合条件逻辑:
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])
解决方案 13:
# 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]
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件