这个列表理解是如何工作的?

时间:2014-11-23 00:23:28

标签: python syntax list-comprehension

list1 = ['Hello', 10, None]
list2 = [g.lower() for g in list1 if isinstance(g, str)]
list3 = [g.lower() if isinstance(g,str) else g for g in list1]
list4 = [isinstance(g, str) and g.lower() or g for g in list1]

如果我想将list中的字符串转换为小写,我可以使用list2中的方法,输出将为['hello']

除了这种转换,如果我想保留整数(在这种情况下为10)和Nonelist3list4中的方法都将工作和输出将是['hello', 10, None]

我的问题是我无法理解list4中的方法是如何工作的。

2 个答案:

答案 0 :(得分:4)

首先,编写如下代码:

condition and value1 or value2

是人们在以下方面在Python中实现三元条件运算符的方式:

value1 if condition else value2
由于conditional expression,在版本2.5中引入了

PEP 0308。现在不推荐使用旧方法,而是使用稍微更有效且更易读的新方法。


旧方法的工作原因是andor在Python中的运行方式。这些运算符返回值,而不是像大多数其他语言一样返回布尔结果。

如果a and b评估为a,则a会返回False;否则,它返回b

>>> 0 and 1
0
>>> 1 and 0
0
>>> 1 and 2
2
>>>

如果a or b评估为a,则a会返回True;否则,它返回b

>>> 1 or 0
1
>>> 0 or 1
1
>>> 1 or 2
1
>>>

此外,如果您不知道,0评估为False,而其他所有数字的评估结果为True


来到你的代码,这个:

isinstance(g, str) and g.lower() or g

实际上是由Python解释的:

(isinstance(g, str) and g.lower()) or g

现在,如果isinstance(g, str)返回Falseg不是字符串):

(False and g.lower()) or g
False

返回

and

False or g

然后or返回g。因此,我们避免在非字符串类型上调用.lower()

但是如果isinstance(g, str)返回Trueg是一个字符串):

(True and g.lower()) or g

and返回g.lower()

g.lower() or g

然后or会返回g.lower(),这很好,因为g是一个字符串。


总结一下,这两个表达式:

g.lower() if isinstance(g,str) else g

isinstance(g, str) and g.lower() or g

功能相同。 但请使用第一个!! 另一个是可读性很差。

答案 1 :(得分:1)

引用the doc

  

表达式x and y首先评估x;如果x为假,则为   返回值;否则,将评估y并生成结果值   归还。

     

表达式x or y首先评估x;如果x为真,则其值为   回;否则,将评估y,结果值为   返回。

由于优先规则,isinstance(g, str) and g.lower() or g实际上被评估为 (isinstance(g, str) and g.lower()) or g(乘法优先于加法)。

这基本上意味着以下内容:

  • 如果isinstance(g, str)为真,则会g.lower()的结果
  • 否则g将被采取

如您所见,这与list3操作中的内容相同。