标签: python-internals

运算符'非常奇怪'的行为方法

为什么是第一个结果False,如果不是True

>>> from collections import OrderedDict
>>> OrderedDict.__repr__ is OrderedDict.__repr__
False
>>> dict.__repr__ is dict.__repr__
True
Run Code Online (Sandbox Code Playgroud)

python methods python-2.7 python-internals

47
推荐指数
1
解决办法
2317
查看次数

Python的关闭程序记录在哪里?

CPython有一个奇怪的行为,它在关机期间将模块设置为None.在我写完的一些多线程代码关闭期间,这会搞砸错误记录.

我找不到任何有关此行为的文档.它在PEP 432中提到:

[...]显着减少将遇到"模块全局设置为无"行为的模块数量,该行为用于审议中断周期并尝试干净地释放更多外部资源.

SO有关此问题的提问C API文档中提到的嵌入式翻译关闭行为.

我还在python-dev相关的CPython bug 找到了一个相关的线程:

一旦解除分配,此修补程序不会更改模块对象清除其全局字典的行为.

这种行为记录在哪里?是Python 2具体吗?

python multithreading python-2.7 python-internals

47
推荐指数
1
解决办法
2009
查看次数

当'[]是[]'并且'{}是{}'返回False时,为什么'()是()'返回True?

根据我的意识,使用[], {}()实例化对象会分别返回一个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).如果没有给出参数,构造函数会创建一个新的空元组().

可以说,这还不足以回答我的问题.

那么,为什么空元组具有相同的身份,而其他像列表或词典不具有相同的身份?

python identity tuples python-3.x python-internals

47
推荐指数
1
解决办法
3853
查看次数

Python中的两个变量具有相同的id,但不具有列表或元组

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 identity tuples python-3.x python-internals

44
推荐指数
3
解决办法
6231
查看次数

关于更改不可变字符串的id

关于id类型对象的某些东西str(在python 2.7中)让我很困惑.该str类型是不变的,所以我希望,一旦它被创建,它将始终具有相同的id.我相信我不会这么说自己,所以我会发布一个输入和输出序列的例子.

>>> id('so')
140614155123888
>>> id('so')
140614155123848
>>> id('so')
140614155123808
Run Code Online (Sandbox Code Playgroud)

所以同时,它一直在变化.但是,在指向该字符串的变量之后,事情会发生变化:

>>> so = 'so'
>>> id('so')
140614155123728
>>> so = 'so'
>>> id(so)
140614155123728
>>> not_so = 'so'
>>> id(not_so)
140614155123728
Run Code Online (Sandbox Code Playgroud)

因此,一旦变量保存该值,它就会冻结id.的确,在del so和之后del not_so,id('so')开始的输出再次改变.

这是相同的行为与(小)整数.

我知道不变性和拥有相同之间没有真正的联系id; 仍然,我试图弄清楚这种行为的来源.我相信那些熟悉python内部的人会比我更少惊讶,所以我试图达到同样的目的......

更新

尝试使用不同的字符串会产生不同的结果......

>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
Run Code Online (Sandbox Code Playgroud)

现在它平等的......

python string immutability python-internals

43
推荐指数
1
解决办法
6851
查看次数

为什么`False是False是False`评价为'True`?

为什么在Python中以这种方式进行评估:

>>> False is False is False
True
Run Code Online (Sandbox Code Playgroud)

但是当试用括号时,表现如预期的那样:

>>> (False is False) is False
False
Run Code Online (Sandbox Code Playgroud)

python python-internals

41
推荐指数
4
解决办法
3610
查看次数

'is'运算符与非缓存整数意外地运行

在玩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()的参与对象,这意味着ab指向同一个int函数内声明的时候实例func,但是,相反,它们指向一个不同的对象时,它的外面.

为什么会这样?


注意:我知道identity(is)和equal(==)操作之间的区别,如了解Python的"is"操作符中所述.另外,我也知道python正在对范围内的整数执行缓存,[-5, 256]"is"中所述,运算符与整数一起出现意外行为.

不是这里的情况,因为数字超出了该范围,我确实想要评估身份而不是平等.

python int identity python-3.x python-internals

41
推荐指数
2
解决办法
1420
查看次数

为什么dict查找总是比列表查找更好?

我使用字典作为查找表,但我开始怀疑列表是否会更适合我的应用程序 - 查找表中的条目数量不是那么大.我知道列表在引擎盖下使用C数组,这使我得出结论,在列表中只查找几个项目比在字典中更好(访问数组中的一些元素比计算哈希更快).

我决定介绍其他选择,但结果让我感到惊讶.列表查找只有单个元素才能更好!请参见下图(log-log plot):

list vs dict查找时间

所以问题就出现了:为什么列表查找执行得如此糟糕?我错过了什么?

在一个侧面问题上,在大约1000个条目之后,在dict查找时间中引起我注意的其他东西是一个小"不连续".我单独绘制了dict查找时间来显示它.

字典查找时间

ps1我知道数组和散列表的O(n)vs O(1)摊销时间,但通常情况下,迭代数组的少量元素比使用散列表更好.

ps2这是我用来比较字典和列表查找时间的代码:

import timeit

lengths = [2 ** i for i in xrange(15)]

list_time = []
dict_time = []
for l in lengths:
    list_time.append(timeit.timeit('%i in d' % (l/2), 'd=range(%i)' % l))
    dict_time.append(timeit.timeit('%i in d' % (l/2),
                                   'd=dict.fromkeys(range(%i))' % l))
    print l, list_time[-1], dict_time[-1]
Run Code Online (Sandbox Code Playgroud)

ps3使用Python 2.7.13

python optimization performance big-o python-internals

41
推荐指数
2
解决办法
4677
查看次数

为什么在Python中反转和排序不同的类型?

reversed的类型是"类型":

>>> type(reversed)
<class 'type'>
Run Code Online (Sandbox Code Playgroud)

sorted的类型是"内置函数或方法":

>>> type(sorted)
<class 'builtin_function_or_method'>
Run Code Online (Sandbox Code Playgroud)

但是,它们在性质上看起来是一样的.排除功能上的明显差异(逆转与排序序列),实现这种差异的原因是什么?

python types python-internals

39
推荐指数
2
解决办法
2270
查看次数

为什么这个循环比创建字典的字典理解更快?

我不是来自软件/计算机科学背景,但我喜欢用Python编写代码,并且通常可以理解为什么事情变得更快.我真的很想知道为什么这个for循环比字典理解运行得更快.任何见解?

问题:给定a带有这些键和值的字典,返回一个字典,其值为键,键为值.(挑战:在一行中做到这一点)

和代码

a = {'a':'hi','b':'hey','c':'yo'}

b = {}
for i,j in a.items():
    b[j]=i

%% timeit 932 ns ± 37.2 ns per loop

b = {v: k for k, v in a.items()}

%% timeit 1.08 µs ± 16.4 ns per loop
Run Code Online (Sandbox Code Playgroud)

python performance python-3.x python-internals dictionary-comprehension

39
推荐指数
2
解决办法
4439
查看次数