当前位置: 首页 > 面试题库 >

当python添加小整数时,幕后会发生什么?

徐英锐
2023-03-14
问题内容

id最近在摆弄东西,意识到(c?)Python所做的事情非常明智:它确保小整数始终具有相同的id

>>> a, b, c, d, e = 1, 2, 3, 4, 5
>>> f, g, h, i, j = 1, 2, 3, 4, 5
>>> [id(x) == id(y) for x, y in zip([a, b, c, d, e], [f, g, h, i, j])]
[True, True, True, True, True]

但是后来我想知道数学运算的结果是否同样如此。原来是:

>>> nines = [(x + y, 9) for x, y in enumerate(reversed(range(10)))]
>>> [id(x) == id(y) for x, y in nines]
[True, True, True, True, True, True, True, True, True, True]

似乎它开始在n = 257处失败…

>>> a, b = 200 + 56, 256
>>> id(a) == id(b)
True
>>> a, b = 200 + 57, 257
>>> id(a) == id(b)
False

但是有时即使更大的数量它仍然可以工作:

>>> [id(2 * x + y) == id(300 + x) for x, y in enumerate(reversed(range(301)))][:10]
[True, True, True, True, True, True, True, True, True, True]

这里发生了什么?python如何做到这一点?


问题答案:

Python会int以一定数量保留对象池。当您在该范围内创建一个时,您实际上会获得对已有对象的引用。我怀疑这是出于优化原因。

对于超出该池范围的数字,每当您尝试创建一个新对象时,您似乎都会取回该对象。

$ python
Python 3.2 (r32:88445, Apr 15 2011, 11:09:05) 
[GCC 4.5.2 20110127 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 300
>>> id(x)
140570345270544
>>> id(100+200)
140570372179568
>>> id(x*2)
140570345270512
>>> id(600)
140570345270576

资源

PyObject * PyInt_FromLong(long ival)返回值:新参考。创建一个新的整数对象,其值为ival。

当前的实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建int时,您实际上只是返回对现有对象的引用。
因此应该可以更改1的值。我怀疑在这种情况下Python的行为是不确定的。:-)

重点矿



 类似资料:
  • 问题内容: 我们有多个线程调用上。 我的理论是,当由两个线程同时调用时,实际上仅将要添加的两个对象之一添加到。这看似合理吗? 如果是这样,您如何解决呢?使用类似吗? 问题答案: 对于ArrayList上的两个线程同时调用add时发生的情况,没有任何保证的行为。但是,根据我的经验,两个对象的添加都很好。与列表相关的大多数线程安全问题在添加/删除时都会处理迭代。尽管如此,我强烈建议不要将Vanilla

  • 之后我添加工具:替换="android: appComponentFactory在我的Manifest.xml它使发生错误 我只是按照日志给我的建议去做 我已经尝试了从这里开始的所有操作,Android X:tools:replace在第:行为属性指定,但没有指定新值 它向我展示了错误 这是我的Logcat 这是我的舱单

  • 问题内容: 就速度和内存效率而言,在函数内部导入Python模块和/或函数有什么优缺点? 它是否在每次运行该功能时重新导入,或者是否仅在运行一开始就重新导入一次? 问题答案: 每次运行该功能时都会重新导入吗? 没有; 确切地说,Python模块在每次导入时都会被缓存,因此导入第二(或第三或第四…)次实际上并不会迫使它们再次经历整个导入过程。1个 是否在开始时导入一次功能是否运行? 不可以,只有在执

  • 注意:我不是iptables的高级用户,但我知道它的基本工作原理。

  • 我在yarn cluster上运行的spark应用程序崩溃了,我正在试图确定根本原因。在我使用从yarn获得的日志中,我看到在块获取期间有一大堆连接被拒绝,还有一个内存不足错误。很难说出根本原因是什么。我的问题是当容器因为OutOfMemory异常而被杀死时会发生什么。因此,在容器日志中,我看到这是如何在容器上启动执行器的 我还看到许多。在应用程序崩溃之前,似乎有多个这样的问题。spark重试一个

  • 我做了研究,发现应该这样做我不知道java对象像指针一样工作。我以为只有当两个对象相等时才会传递值。我甚至创建了一个简单的测试应用程序,它可以设置和获取一个对象的数量。再一次,我把这两个对象都等同起来。更改一个对象的元素似乎也会影响另一个对象。我不知道该怎么在谷歌上搜索这个。所以我才把整个故事都告诉你。我只得到与c编程有关的文档。我觉得我的底子都碎了。我现在才知道是如何工作的。我试着做 这不影响N