这个列表推导式是如何工作的?

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

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

除了进行这种转换之外,如果我想要保留整数(在本例中为10)和None,那么list3list4中的方法都可以,输出将会是['hello', 10, None]

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


2
不要使用“list”作为名称,“list”是一个内置函数,最好不要动它。 - gboffi
@gboffi 那么列表,字符串,字典,元组等都是内置函数吗? - user3454011
请发布您正在使用的实际代码。目前来看,第2行应该会给您一个错误。 - inspectorG4dget
当你创建list2时,你引用了它。我在我的机器上尝试了一下,它报错了。你可能需要在第二行将list2替换为list。 - Yair Daon
另外,在我的Python(2.7.3)中,list2到list4都是['hello']。你确定你的代码正确吗? - Yair Daon
显示剩余2条评论
2个回答

4

要开始,编写类似这样的代码:

condition and value1 or value2

在此之前,人们是如何在Python中实现三元条件运算符的:
value1 if condition else value2

由于PEP 0308条件表达式在2.5版本中被引入。现在使用旧方法已经被弃用,而更高效、更易读的新方法则取而代之。


旧方法之所以有效,是因为在Python中,andor的操作方式不同于大多数其他语言,这些运算符返回值而不是布尔结果。

执行a and b,如果a求值为False,则返回a;否则,返回b

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

a 或 b 的运算结果为 a,如果 aTrue;否则返回 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

and 返回 False

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

引用文档:

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

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

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

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

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

如你所见,这与list3操作中的相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接