标签: python-internals

Python 3中不同的对象大小True和False

__sizeof__在不同的Python对象上尝试使用魔术方法(特别是)我偶然发现了以下行为:

Python 2.7

>>> False.__sizeof__()
24
>>> True.__sizeof__()
24
Run Code Online (Sandbox Code Playgroud)

Python 3.x

>>> False.__sizeof__()
24
>>> True.__sizeof__()
28
Run Code Online (Sandbox Code Playgroud)

Python 3中改变了什么使得大小True超过了False

python cpython python-2.7 python-3.x python-internals

67
推荐指数
4
解决办法
2884
查看次数

列表理解过滤 - "set()陷阱"

一个相当常见的操作是list基于另一个过滤一个list.人们很快发现这个:

[x for x in list_1 if x in list_2]
Run Code Online (Sandbox Code Playgroud)

大输入速度慢 - 它是O(n*m).呸.我们如何加快速度?使用a set进行过滤查找O(1):

s = set(list_2)
[x for x in list_1 if x in s]
Run Code Online (Sandbox Code Playgroud)

这给出了很好的整体O(n)行为.然而,我经常看到即使是经验丰富的编码员也会陷入The Trap ™:

[x for x in list_1 if x in set(list_2)]
Run Code Online (Sandbox Code Playgroud)

确认!这也是O(n*m),因为python set(list_2) 每次构建,而不仅仅是一次.


我认为那是故事的结尾 - python无法优化它只能构建set一次.请注意陷阱.要忍受它.嗯.

#python 3.3.2+
list_2 = list(range(20)) #small for demonstration purposes
s = set(list_2)
list_1 = list(range(100000))
def f():
    return [x for x in list_1 if x in s] …
Run Code Online (Sandbox Code Playgroud)

python python-3.x python-internals

65
推荐指数
5
解决办法
4034
查看次数

为什么更简单的循环速度更慢?

调用 with n = 10**8,对我来说,简单循环始终比复杂循环慢得多,我不明白为什么:

def simple(n):
    while n:
        n -= 1

def complex(n):
    while True:
        if not n:
            break
        n -= 1
Run Code Online (Sandbox Code Playgroud)

有时以秒为单位:

def simple(n):
    while n:
        n -= 1

def complex(n):
    while True:
        if not n:
            break
        n -= 1
Run Code Online (Sandbox Code Playgroud)

这是字节码的循环部分,如下所示dis.dis(simple)

  6     >>    6 LOAD_FAST                0 (n)
              8 LOAD_CONST               1 (1)
             10 BINARY_OP               23 (-=)
             14 STORE_FAST               0 (n)

  5          16 LOAD_FAST                0 (n)
             18 POP_JUMP_BACKWARD_IF_TRUE     7 (to 6)
Run Code Online (Sandbox Code Playgroud)

对于complex

 10     >>    4 …
Run Code Online (Sandbox Code Playgroud)

python performance cpython python-internals python-3.11

62
推荐指数
1
解决办法
9685
查看次数

为什么类__dict__是mappingproxy?

我想知道为什么一个类__dict__是一个类mappingproxy,但实例__dict__只是一个简单的例子dict

>>> class A:
...     pass

>>> a = A()
>>> type(a.__dict__)
<class 'dict'>
>>> type(A.__dict__)
<class 'mappingproxy'>
Run Code Online (Sandbox Code Playgroud)

python class python-3.x python-internals

60
推荐指数
3
解决办法
8491
查看次数

Python中的__weakref__究竟是什么?

令人惊讶的是,没有明确的文档__weakref__.这里解释弱引用.__weakref__也很快在文档中提到__slots__.但我找不到任何关于__weakref__它自己的东西.

到底是__weakref__什么? - 它只是一个作为标志的成员:如果存在,该对象可能被弱引用? - 或者它是一个可以被覆盖/分配以获得所需行为的函数/变量?怎么样?

python python-3.x python-internals

57
推荐指数
3
解决办法
1万
查看次数

为什么对于 bytearray 来说 b.pop(0) 比 del b[0] 慢 200 多倍?

让他们竞争 3 次(每次 100 万次弹出/删除):

\n
from timeit import timeit\n\nfor _ in range(3):\n    t1 = timeit(\'b.pop(0)\', \'b = bytearray(1000000)\')\n    t2 = timeit(\'del b[0]\', \'b = bytearray(1000000)\')\n    print(t1 / t2)\n
Run Code Online (Sandbox Code Playgroud)\n

时间比例(在线尝试!):

\n
274.6037053753368\n219.38099365582403\n252.08691226683823\n
Run Code Online (Sandbox Code Playgroud)\n

为什么pop做同样的事情要慢得多?

\n

python arrays performance cpython python-internals

57
推荐指数
2
解决办法
6156
查看次数

Set literal给出了set函数调用的不同结果

为什么set函数调用会消除欺骗,但解析集合文字却没有?

>>> x = Decimal('0')
>>> y = complex(0,0)
>>> set([0, x, y])
{0}
>>> {0, x, y}
{Decimal('0'), 0j}
Run Code Online (Sandbox Code Playgroud)

(Python 2.7.12.可能与类似问题的根本原因相同)

python hash set python-2.x python-internals

56
推荐指数
2
解决办法
2667
查看次数

为什么字符串的开头慢于?

令人惊讶的是,我发现startswith速度比in:

In [10]: s="ABCD"*10

In [11]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 307 ns per loop

In [12]: %timeit "XYZ" in s
10000000 loops, best of 3: 81.7 ns per loop
Run Code Online (Sandbox Code Playgroud)

众所周知,in操作需要搜索整个字符串,startswith只需要检查前几个字符,所以startswith应该更有效率.

什么时候s足够大,startswith速度更快:

In [13]: s="ABCD"*200

In [14]: %timeit s.startswith("XYZ")
1000000 loops, best of 3: 306 ns per loop

In [15]: %timeit "XYZ" in s
1000000 loops, best of 3: 666 ns per loop
Run Code Online (Sandbox Code Playgroud)

所以看起来调用 …

python cpython startswith python-2.7 python-internals

55
推荐指数
1
解决办法
3336
查看次数

"from __future__ import braces"代码在哪里?

我想知道在命令上执行的代码究竟是什么:

>>> from __future__ import braces
SyntaxError: not a chance
Run Code Online (Sandbox Code Playgroud)

所以,因为python是开源的,我打开C:\Python27\Lib\__future__.py并查看.令人惊讶的是,我发现没有处理导入braces模块的东西.

所以,我的问题是,处理这个问题的代码在哪里?当我运行该命令时会发生什么?

python python-2.7 python-internals

54
推荐指数
1
解决办法
2万
查看次数

为什么在Python 3中范围(0)==范围(2,2,2)为真?

为什么使用不同值初始化的范围在Python 3中相互比较?

当我在我的解释器中执行以下命令时:

>>> r1 = range(0)
>>> r2 = range(2, 2, 2)
>>> r1 == r2
True
Run Code Online (Sandbox Code Playgroud)

结果是True.为什么会这样?为什么range具有不同参数值的两个不同对象被视为相等?

python identity range python-3.x python-internals

53
推荐指数
5
解决办法
1万
查看次数