是否可以在列表理解中使用'else'?

时间:2010-06-01 16:57:10

标签: python list-comprehension

以下是我试图变成列表理解的代码:

table = ''
for index in xrange(256):
    if index in ords_to_keep:
        table += chr(index)
    else:
        table += replace_with

有没有办法将else语句添加到此理解中?

table = ''.join(chr(index) for index in xrange(15) if index in ords_to_keep)

6 个答案:

答案 0 :(得分:284)

语法a if b else c是Python中的三元运算符,如果条件a为真,则求值为b - 否则,它将计算为c。它可以用在理解陈述中:

>>> [a if a else 2 for a in [0,1,0,3]]
[2, 1, 2, 3]

所以对你的例子来说,

table = ''.join(chr(index) if index in ords_to_keep else replace_with
                for index in xrange(15))

答案 1 :(得分:15)

如果你想要一个else,你不想过滤列表理解,你希望它迭代每个值。您可以使用true-value if cond else false-value作为语句,并从末尾删除过滤器:

table = ''.join(chr(index) if index in ords_to_keep else replace_with for index in xrange(15))

答案 2 :(得分:8)

要在python编程中使用列表推导中的else,您可以尝试下面的代码段。这将解决您的问题,该代码段在python 2.7和python 3.5上进行测试。

obj = ["Even" if i%2==0 else "Odd" for i in range(10)]

答案 3 :(得分:5)

else可以在list comprehension 内使用Conditional Expression("三元运算符&#34)在Python中使用):

>>> [("A" if b=="e" else "c") for b in "comprehension"]
['c', 'c', 'c', 'c', 'c', 'A', 'c', 'A', 'c', 'c', 'c', 'c', 'c']

这里,括号"()"只是为了强调条件表达式,它们不一定是必需的(Operator precedence)。

另外,可以嵌套多个表达式,导致更多else s并且难以阅读代码:

>>> ["A" if b=="e" else "d" if True else "x" for b in "comprehension"]
['d', 'd', 'd', 'd', 'd', 'A', 'd', 'A', 'd', 'd', 'd', 'd', 'd']
>>>

在相关的说明中,理解也可以在最后包含自己的if条件:

>>> ["A" if b=="e" else "c" for b in "comprehension" if False]
[]
>>> ["A" if b=="e" else "c" for b in "comprehension" if "comprehension".index(b)%2]
['c', 'c', 'A', 'A', 'c', 'c']

条件的取值?是的,多个if是可能的,实际上也是多个for

>>> [i for i in range(3) for _ in range(3)]
[0, 0, 0, 1, 1, 1, 2, 2, 2]
>>> [i for i in range(3) if i for _ in range(3) if _ if True if True]
[1, 1, 2, 2]

(单个下划线_是Python中的有效变量名称(identifier),此处仅用于显示未实际使用。 a special meaning in interactive mode

使用它来获得额外的条件表达式是可能的,但没有实际用途:

>>> [i for i in range(3)]
[0, 1, 2]
>>> [i for i in range(3) if i]
[1, 2]
>>> [i for i in range(3) if (True if i else False)]
[1, 2]

理解也可以嵌套来创造多维"列表("数组"):

>>> [[i for j in range(i)] for i in range(3)]
[[], [1], [2, 2]]

最后但同样重要的是,理解不仅限于创建list,即elseif也可以在set理解中以相同的方式使用:

>>> {i for i in "set comprehension"}
{'o', 'p', 'm', 'n', 'c', 'r', 'i', 't', 'h', 'e', 's', ' '}

dictionary理解:

>>> {k:v for k,v in [("key","value"), ("dict","comprehension")]}
{'key': 'value', 'dict': 'comprehension'}

同样的语法也用于Generator Expressions

>>> for g in ("a" if b else "c" for b in "generator"):
...     print(g, end="")
...
aaaaaaaaa>>>

可用于创建tuplethere is no tuple comprehension)。

<小时/> 进一步阅读:

答案 4 :(得分:2)

很棒的答案,但只是想提一下&#34;传递&#34;关键字在list-comprehension的if / else部分不起作用(如上面提到的例子中所述)。

#works
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else x**2 for x in list1 ]
print(newlist2, type(newlist2))

#but this WONT work
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else pass for x in list1 ]
print(newlist2, type(newlist2))

这是在python 3.4上尝试和测试的。 错误如下:

newlist2 = [x if x > 30 else pass for x in list1 ]                                    
SyntaxError: invalid syntax

因此,尽量避免列表推导中的传递

答案 5 :(得分:1)

  

另外,我是否正确地认为列表理解是最有效的方法?

也许。列表推导本身并不具有计算效率。它仍在线性时间内运行。

根据我的个人经验: 通过使用上面的for-loop / list-appending类型结构替换列表推导(特别是嵌套的),我在处理大型数据集时大大减少了计算时间。在这个应用程序中,我怀疑你会注意到差异。