如果 / 否则列表理解?

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

答案

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

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

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


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

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

单程:

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 内联。

这是另一个说明性示例:

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

它利用了以下事实: if i对函数range()生成的所有其他值求值为0if i False ,而对值求值为True 。因此,列表理解评估如下:

>>> ["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的第一个列表理解中,顺序为:

如果 条件 迭代 表达式

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

表达式 如果 条件 别的 表达式 2 迭代 项目

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

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

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

if

box_of_apples 如果 extract_apple 苹果 apple_is_ripe

if/else

如果 mark_apple apple_is_ripe 其他 leave_it_unmarked 苹果 box_of_apples

其他解决方案对于单个if / else结构非常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', '']

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

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

从迭代列表中列出项目

最好首先概括所有可能的形式,而不是给出问题的具体答案。否则,读者将不知道答案是如何确定的。这是我在尝试确定是否可以在最后一个形式中使用 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的值不需要在任何条件子句中使用。 conditional3可用作将值添加或不添加到输出列表的开关。

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

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

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

请记住以下几点:

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