if / else在列表理解中?

时间:2010-11-23 19:56:45

标签: python list-comprehension

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

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

本质:

  1. 用空字符串替换所有Nones,然后
  2. 执行功能。

11 个答案:

答案 0 :(得分:1024)

你可以完全这样做,这只是一个订购问题:

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

请注意,这实际上使用的是另一种语言结构,conditional expression,它本身不属于comprehension syntaxif之后的for…invalue = 123 print(value, 'is', 'even' if value % 2 == 0 else 'odd') 的一部分列表推导并用于从源迭代中过滤元素。


条件表达式可用于您希望根据某些条件在两个表达式值之间进行选择的各种情况。这与ternary operator ?: that exists in other languages相同。例如:

{{1}}

答案 1 :(得分:40)

一种方式:

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

答案 2 :(得分:36)

这是另一个说明性的例子:

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

答案 3 :(得分:24)

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

下面是一个示例,显示了如何在列表理解中编写条件语句:

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

  

expression1 如果 条件 其他 expression2 > 项目 可迭代

我总是很难记住 expresseion1 必须在之前,而 expression2 必须在其他之后。我的头希望两者都在之前或之后。

我猜它是这样设计的,因为它类似于普通语言,例如“如果要下雨,我想留在里面,否则我想去外面”

答案 4 :(得分:4)

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

答案 5 :(得分:1)

您可以做到

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]

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

“从可重复的项目中创建列表”

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

[可迭代项的expression1(item)]

[expression1(item),如果条件1为可迭代项,则为条件]

[如果条件1,则为expression1(item),否则为可迭代项的expression2(item)]

[如果有条件1,则为expression1(item);如果有条件2,则为可迭代项目的expression2(item)]

在任何条件条款中都不需要使用“ item”的值。可以将“ condition3”用作向输出列表添加或不添加值的开关。

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

newlist = [如果是s.strip(),则s为第一名单中的s]

答案 8 :(得分:0)

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

请注意以下几点:

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

答案 10 :(得分:-1)

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

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