Questions tagged «python-internals»

Python如何在引擎盖下工作?用于与(例如)设计决策以及内部数据结构和使用的算法有关的问题。

4
为什么复制经过改组的列表要慢得多?
复制一份随机播放的range(10**6)列表十次需要我大约0.18秒:(这五次运行) 0.175597017661 0.173731403198 0.178601711594 0.180330912952 0.180811964451 复制未整理的列表十次需要我大约0.05秒: 0.058402235973 0.0505464636856 0.0509734306934 0.0526022752744 0.0513324916184 这是我的测试代码: from timeit import timeit import random a = range(10**6) random.shuffle(a) # Remove this for the second test. a = list(a) # Just an attempt to "normalize" the list. for _ in range(5): print timeit(lambda: list(a), number=10) 我也尝试用复制a[:],结果相似(即,速度差异很大) …

1
解释器维护的整数缓存是什么?
深入研究Python的源代码后,我发现它维护了一个PyInt_Objects数组,范围从int(-5)到int(256)(@ src / Objects / intobject.c) 一个小实验证明了这一点: >>> a = 1 >>> b = 1 >>> a is b True >>> a = 257 >>> b = 257 >>> a is b False 但是,如果我在py文件中一起运行这些代码(或使用分号将它们结合在一起),结果将有所不同: >>> a = 257; b = 257; a is b True 我很好奇为什么它们仍然是同一对象,所以我深入研究了语法树和编译器,提出了下面列出的调用层次结构: PyRun_FileExFlags() mod = PyParser_ASTFromFile() …

1
Python:为什么*和**比/和sqrt()快?
在优化代码时,我意识到了以下几点: >>> from timeit import Timer as T >>> T(lambda : 1234567890 / 4.0).repeat() [0.22256922721862793, 0.20560789108276367, 0.20530295372009277] >>> from __future__ import division >>> T(lambda : 1234567890 / 4).repeat() [0.14969301223754883, 0.14155197143554688, 0.14141488075256348] >>> T(lambda : 1234567890 * 0.25).repeat() [0.13619112968444824, 0.1281130313873291, 0.12830305099487305] 并且: >>> from math import sqrt >>> T(lambda : sqrt(1234567890)).repeat() …

2
list()比列表理解使用更多的内存
因此,我在玩list对象时发现一点奇怪的事情:如果list用list()它创建的东西比列表理解力要占用更多的内存?我正在使用Python 3.5.2 In [1]: import sys In [2]: a = list(range(100)) In [3]: sys.getsizeof(a) Out[3]: 1008 In [4]: b = [i for i in range(100)] In [5]: sys.getsizeof(b) Out[5]: 912 In [6]: type(a) == type(b) Out[6]: True In [7]: a == b Out[7]: True In [8]: sys.getsizeof(list(b)) Out[8]: 1008 从文档: …

6
为什么在Python for循环中可以对迭代器和序列使用相同的名称?
这更多是一个概念上的问题。最近,我在Python中看到了一段代码(它在2.7中有效,它也可能在2.5中运行过),其中一个for循环对要迭代的列表和列表中的项目使用相同的名称,这既使我感到不道德,也使它不起作用。 例如: x = [1,2,3,4,5] for x in x: print x print x 产量: 1 2 3 4 5 5 现在,对我来说有意义的是,最后打印出的值将是循环中分配给x的最后一个值,但是我无法理解为什么您能够在for循环的两个部分中使用相同的变量名并具有它按预期起作用。它们在不同的范围内吗?允许这种事情发生的事情到底是怎么回事?

2
为什么使用中间变量的代码要比不使用中间变量的代码快?
我遇到这种奇怪的行为,但无法解释。这些是基准: py -3 -m timeit "tuple(range(2000)) == tuple(range(2000))" 10000 loops, best of 3: 97.7 usec per loop py -3 -m timeit "a = tuple(range(2000)); b = tuple(range(2000)); a==b" 10000 loops, best of 3: 70.7 usec per loop 与使用变量分配进行比较,为什么比使用带有临时变量的班轮快27%以上呢? 通过Python文档,垃圾回收在timeit期间被禁用,因此并非如此。这是某种优化吗? 结果也可以在Python 2.x中重现,尽管程度较小。 运行Windows 7,CPython 3.5.1,Intel i7 3.40 GHz,64位OS和Python。似乎我尝试使用Python 3.5.0在Intel i7 3.60 …




1
为什么在失败的int转换中此Python字符串的大小会更改
从这里的推文中: import sys x = 'ñ' print(sys.getsizeof(x)) int(x) #throws an error print(sys.getsizeof(x)) 对于两个getsizeof调用,我们得到74个字节,然后是77个字节。 看来我们从失败的int调用中向对象添加了3个字节。 来自Twitter的更多示例(您可能需要重新启动python才能将大小重置为74): x = 'ñ' y = 'ñ' int(x) print(sys.getsizeof(y)) 77! print(sys.getsizeof('ñ')) int('ñ') print(sys.getsizeof('ñ')) 74,然后77。

3
Python中的__weakref__到底是什么?
令人惊讶的是,没有明确的文档__weakref__。弱引用在这里解释。__weakref__的文档中也简短提及__slots__。但是我找不到任何关于__weakref__自己的东西。 到底是__weakref__什么?-它只是充当标志的成员:如果存在,则该对象可能被弱引用?-还是可以重写/分配以获得所需行为的函数/变量?怎么样?

5
列表理解过滤-“ set()陷阱”
一个合理的常见操作是list基于另一个过滤list。人们很快发现: [x for x in list_1 if x in list_2] 对于大输入而言,速度很慢-为O(n * m)。uck 我们如何加快速度?使用aset进行过滤查找O(1): s = set(list_2) [x for x in list_1 if x in s] 这给出了很好的整体O(n)行为。但是,我经常看到甚至资深的编码人员也落入The Trap ™: [x for x in list_1 if x in set(list_2)] 阿克!这也是O(n * m),因为pythonset(list_2) 每次都构建,而不仅仅是一次构建。 我以为故事就此结束了-python无法优化它,只能构建set一次。只是要注意陷阱。要忍受它。嗯 #python 3.3.2+ list_2 = list(range(20)) #small for …

4
为什么在迭代时添加到集合中和从集合中删除时会得到这么多迭代?
为了理解Python的for循环,我认为这会给出{1}一次迭代的结果,或者只是陷入无限循环,这取决于它是否像C语言或其他语言那样进行迭代。但是实际上它都没有。 >>> s = {0} >>> for i in s: ... s.add(i + 1) ... s.remove(i) ... >>> print(s) {16} 为什么要进行16次迭代?结果{16}从何而来? 这是使用Python 3.8.2。在pypy上可以达到预期的效果{1}。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.