如果/否则列表理解


Answers:


1453

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

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

请注意,这实际上使用了一种不同的语言构造,即条件表达式,它本身不是理解语法的一部分,而ifafter则for…in是列表理解的一部分,用于从可迭代的源中筛选元素。


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

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

141
请注意,此处的if / else现在是“三元运算符”语法,而不是列表理解语法。
亚当·范登堡

8
这就是为什么我更喜欢将三元运算符放在方括号中,这使它更清楚地表明它只是一个普通表达式,而不是一个理解。
Jochen Ritzel

17
所以诀窍是“在列表压缩中,如果我之前写过,那么我也必须添加其他部分”。因为如果我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]。很抱歉打扰。感谢您的回答。
Grijesh Chauhan 2013年

5
蟒蛇文档提到的三元运算符。请注意,它需要else,否则将不起作用。
naught101

4
@Drewdin列表推导不支持在迭代过程中中断。然后,您将必须使用普通循环。

44

单程:

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

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

虽然您有:

row = map(change, row)

或者您可以使用lambda内联。


13
当您必须处理ifelse语句块或s语句块中的表达式或代码可能出现的异常时,这也是一种很好的(也许只是)使用的技术。对于简单的情况,可接受的答案更好。
martineau 2010年

37

这是另一个说明性示例:

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

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

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

37

前面的答案已经解决了特定的问题,因此我将解决在列表推导中使用条件语句的一般想法。

这是一个示例,显示了如何在列表推导中编写条件语句:

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,顺序为:

表达 项目 迭代 如果 条件

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

表达式 如果 条件 其他 表达式2 项目 迭代

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

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

用普通的英语,上面提到的两种列表理解可以表述为:

仅使用if

extract_apple 苹果 box_of_apples 如果 apple_is_ripe

if/else

mark_apple, 如果 apple_is_ripe 其他 ,则box_of_apples 中将 苹果标记为未 标记


7

其他解决方案非常适合单个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', '']

1

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

请记住以下几点:

[ 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

0

不需要三元if / then / else。我认为您的问题需要这个答案:

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

0

从迭代列表中列出项目

最好首先概括所有可能的形式,而不是给出问题的具体答案。否则,读者将不知道答案是如何确定的。这是我在尝试确定是否可以在最后一种形式中使用final'子句之前想出的几种通用形式。

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

1
正如Tim 在评论中回答的那样,第二个错误给出了错误,另请参见python文档中的条件语句。这对我来说是很难读的。摘要:仅this if condition else that允许使用正则表达式。不能value = this if condition(可以通过实现value = this if condition else None
Anderium

0

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

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

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


什么是“Affichage去......”是什么意思?是法国人吗?
Peter Mortensen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.