我有一个包含字符串和None值的列表xs。如何使用列表理解来调用每个字符串上的函数,但将None值转换为“”(而不是将它们传递给函数)?

我尝试了:

[f(x) for x in xs if x is not None else '']

但它给出了SyntaxError。正确的语法是什么?


如果您试图创建一个省略基于条件的值的列表理解,请参阅带条件的列表理解。

如果需要考虑两个以上的条件结果,请注意Python的条件表达式不支持elif。相反,需要嵌套if/else条件。有关详细信息,请参见列表理解条件中的“elif”。


当前回答

下面是另一个示例:

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

它利用了这样一个事实,即如果我对0求值为False,对函数range()生成的所有其他值求值为True。因此,列表理解评估如下:

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

其他回答

从可迭代的

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

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

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

具体的问题已经在前面的答案中解决了,所以我将阐述在列表理解中使用条件的一般思想。

下面是一个例子,说明如何在列表理解中编写条件句:

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可迭代项

我总是觉得很难记住表达式1必须在if之前,表达式2必须在else之后。我的头脑希望两者都在之前或之后。

我想它是这样设计的,因为它类似于正常语言,例如“如果下雨,我想呆在里面,否则我想出去”

在普通英语中,上述两种类型的列表理解可以表述为:

仅当:

如果苹果是管道,则在苹果盒中提取苹果

和if/else

如果apple-is_pipe,则标记apple,否则在apple_box中为apple-it_unmark

单向:

def change(x):
    if x is None:
        return f(x)
    else:
        return ''

result = [change(x) for x in xs]

尽管你有:

result = map(change, xs)

或者可以使用lambda内联。

# 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我的联系列表[0,1,2,3,4,5]我的联系结果列表[0,5,4,7,8,9]

因此,对于您:row=[(“”,unicode(x.strip()))[x不是None](对于行中的x)]

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

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