使用"is"运算符或"=="运算符来比较Python中的两个数字是否更好?
例子:
>>> a = 1
>>> a is 1
True
>>> a == 1
True
>>> a is 0
False
>>> a == 0
False
Run Code Online (Sandbox Code Playgroud) 根据我的意识,使用[], {}或()实例化对象会分别返回一个list, dict或新的实例tuple; 具有新标识的新实例对象.
这对我来说非常清楚,直到我实际测试它并且我注意到() is ()实际返回True而不是预期False:
>>> () is (), [] is [], {} is {}
(True, False, False)
Run Code Online (Sandbox Code Playgroud)
正如所料,与创建对象时,这种行为还表现list(),dict()并tuple()分别为:
>>> tuple() is tuple(), list() is list(), dict() is dict()
(True, False, False)
Run Code Online (Sandbox Code Playgroud)
我可以在状态文档中tuple()找到的唯一相关信息:
[...]例如,
tuple('abc')退货('a', 'b', 'c')和tuple([1, 2, 3])退货(1, 2, 3).如果没有给出参数,构造函数会创建一个新的空元组().
可以说,这还不足以回答我的问题.
那么,为什么空元组具有相同的身份,而其他像列表或词典不具有相同的身份?
我做了几个布尔比较:
>>> (True or False) is True
True
>>> (True or False) == True
True
Run Code Online (Sandbox Code Playgroud)
这听起来像==和is是布尔值互换.
有时使用起来更清楚 is
我想知道:
是True和Falsepython中预分配?
是bool(var)始终返回相同True(或False与预分配)True(或False)?
它是安全的替代==与is比较布尔值?
这不是最佳实践.
我只是想知道真相.
Python中的两个变量具有相同的id:
a = 10
b = 10
a is b
>>> True
Run Code Online (Sandbox Code Playgroud)
如果我拿两个lists:
a = [1, 2, 3]
b = [1, 2, 3]
a is b
>>> False
Run Code Online (Sandbox Code Playgroud)
根据这个链接, Senderle回答说,不可变对象引用具有相同的id,而像列表这样的可变对象具有不同的id.
所以现在根据他的回答,元组应该有相同的ID - 意思是:
a = (1, 2, 3)
b = (1, 2, 3)
a is b
>>> False
Run Code Online (Sandbox Code Playgroud)
理想情况下,由于元组不可变,它应该返回True,但它正在返回False!
解释是什么?
在玩Python解释器时,我偶然发现了关于is运算符的这个冲突的情况:
如果评估发生在它返回的函数中True,如果它在外部完成则返回False.
>>> def func():
... a = 1000
... b = 1000
... return a is b
...
>>> a = 1000
>>> b = 1000
>>> a is b, func()
(False, True)
Run Code Online (Sandbox Code Playgroud)
由于is运营商评估id()的参与对象,这意味着a并b指向同一个int函数内声明的时候实例func,但是,相反,它们指向一个不同的对象时,它的外面.
为什么会这样?
注意:我知道identity(is)和equal(==)操作之间的区别,如了解Python的"is"操作符中所述.另外,我也知道python正在对范围内的整数执行缓存,[-5, 256]如"is"中所述,运算符与整数一起出现意外行为.
这不是这里的情况,因为数字超出了该范围,我确实想要评估身份而不是平等.
下面的代码给出了不同的输出Python2和在Python3:
from sys import version
print(version)
def execute(a, st):
b = 42
exec("b = {}\nprint('b:', b)".format(st))
print(b)
a = 1.
execute(a, "1.E6*a")
Run Code Online (Sandbox Code Playgroud)
Python2 打印:
2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)]
('b:', 1000000.0)
1000000.0
Run Code Online (Sandbox Code Playgroud)
Python3 打印:
3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)]
b: 1000000.0
42
Run Code Online (Sandbox Code Playgroud)
为什么Python2将函数b内部的变量绑定到execute函数字符串中的exec值,Python3而不执行此操作?我怎样才能实现Python2in 的行为Python3?我已经尝试将全局和本地的字典传递给exec函数Python3,但到目前为止还没有任何工作.
---编辑---
在阅读了Martijns的回答后,我进一步分析了这一点 …
在Python 3.4中,我们在标准库中获得了一个Enum lib : enum. 我们可以enum使用Python 2.4到2.7(甚至3.1到3.3),pypi中的enum34来获得一个后端.
但是,如果没有这个新模块,我们已经相处了很长一段时间 - 那么为什么我们现在拥有它呢?
我对其他语言的枚举目的有一个大概的了解.在Python中,通常使用如下的裸类并将其称为枚举:
class Colors:
blue = 1
green = 2
red = 3
Run Code Online (Sandbox Code Playgroud)
这可以在API中用于创建值的规范表示,例如:
function_of_color(Colors.green)
Run Code Online (Sandbox Code Playgroud)
如果这有任何批评,它是可变的,你不能迭代它(很容易),我们如何知道整数的语义2?
那么我想我可以使用像namedtuple这样的东西,它是不可变的?
>>> Colors = namedtuple('Colors', 'blue green red')
>>> colors = Colors('blue', 'green', 'red')
>>> colors
Colors(blue='blue', green='green', red='red')
>>> list(colors)
['blue', 'green', 'red']
>>> len(colors)
3
>>> colors.blue
'blue'
>>> colors.index(colors.blue)
0
Run Code Online (Sandbox Code Playgroud)
namedtuple的创建有点多余(我们必须将每个名称写两次),因此有点不优雅.获得颜色的"数字"也有点不优雅(我们必须写colors两次).必须使用字符串进行值检查,效率稍低.
所以回到枚举.
枚举的目的是什么?他们为语言创造了什么价值?我何时应该使用它们,何时应该避免使用它们?
我今天开始学习Python,我想出了创建一个程序,打印从0到10 000的所有素数的想法.我设法让我的程序打印出所有质数,直到251,此时它停止打印出数字.为什么这样做?
这是代码:
for numberToCheck in range(2,10000):
divider = 2
while numberToCheck > divider:
if numberToCheck % divider is 0:
break
else:
divider += 1
if numberToCheck is divider:
print(numberToCheck, "is a prime number.")
Run Code Online (Sandbox Code Playgroud) 我的交互式控制台的简短记录:
Python 2.7.2 (default, Jun 29 2011, 11:10:00)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> True
True
>>> 0 == True
False
>>> 1 == True
True
>>> 2 == True
False
Run Code Online (Sandbox Code Playgroud)
这究竟是为什么呢?
编辑:为了对比起见,请考虑is操作员.
>>> 0 is False
False
>>> 1 is True
False
>>> 0 is 0
True
>>> True is True
True
Run Code Online (Sandbox Code Playgroud)
这使得有很大的意义,因为虽然1和True都意味着同样的事,作为一个条件if语句,他们真的是不一样的东西.
再次编辑:更有趣的后果1 …
>>> class BOOL(bool):
... print "why?"
...
why?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
type 'bool' is not an acceptable base type
Run Code Online (Sandbox Code Playgroud)
我以为Python信任程序员.
python ×10
python-3.x ×4
identity ×3
tuples ×2
boolean ×1
enums ×1
exec ×1
int ×1
python-2.7 ×1
restriction ×1