小编Pao*_*ila的帖子

为什么即使 PYTHONHASHSEED=0,Python 集合的顺序也不确定?

我正在开发一个基于代理的模型,其中我使用不同类型的代理类,这些类的实例被分配给不同类型的对象,例如学校、公司、家庭等。我遇到的问题是我在调试时无法强制执行运行的再现性,由于模型的复杂性,这使得任务变得非常困难。经过长时间的调查,我意识到问题与集合的顺序有关(当然应用了内置的随机和 numpy 随机种子)。即使我设置了 PYHTONHASHSEED=0,我也观察到每次运行时集合的顺序是随机的。当代理移动时,这使得我的模型的每次运行都不同。

当然,我知道套装并不意味着有订单。当从对象中移除代理时,我想使用它们使模型尽可能轻巧和快速。我希望它们的行为是随机的,除非我需要调试引发异常的特定运行。

我添加了以下代码,以便可以验证我的声明。在启动代码之前,我总是通过导出从命令行设置 PYTHONHASHSEED。我从代码打印 PYTHONHASHSEED 值以检查该值是否确实已更新

import os
import random
import numpy as np

print('PYTHON HASH SEED IS', os.environ['PYTHONHASHSEED'])

random.seed(1)
np.random.seed(2)

class S:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __repr__(self):
        return "".join([type(self).__name__, "_{0.a!r}_",
                        "School", "_{0.b!r}" ]).format(self)

list1 = np.random.randint(1, 100,size=40)
list2 = np.random.randint(1, 10,size=40)
d1 = dict()
s1 = set()
d1['students'] = s1
# assign students to d1
for s_id, sch_id in zip(list1, list2):
    d1['students'].add(S(s_id, sch_id))

print(s1)
Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果我使用整数作为集合成员而不是类实例,则无法检测到随机性。问题是否与集合成员是类实例这一事实有关?为什么 ?

当然,我可以重塑代理分配给模型对象的方式,并用列表替换集合,但如果可能的话,我想了解这个问题。我使用的版本是python 3.5.4

python hash set python-3.x

8
推荐指数
1
解决办法
1688
查看次数

当使用用户定义的对象作为键时,为什么Python中的字典查找总是较慢?

我注意到当我使用用户定义的对象(覆盖__hash__方法)作为Python中我的dicts的键时,查找时间至少增加了5倍.

即使我使用非常基本的哈希方法,例如在以下示例中,也会观察到此行为:

class A:
    def __init__(self, a):
        self.a = a
    def __hash__(self):
        return hash(self.a)
    def __eq__(self, other):
        if not isinstance(other, A):
            return NotImplemented
        return (self.a == other.a and self.__class__ == 
                other.__class__)

# get an instance of class A
mya = A(42)
# define dict
d1={mya:[1,2], 'foo':[3,4]}
Run Code Online (Sandbox Code Playgroud)

如果我通过两个不同的键进行访问,我会发现性能存在显着差异

%timeit d1['foo']
Run Code Online (Sandbox Code Playgroud)

结果约为100 ns.而

%timeit d1[mya]
Run Code Online (Sandbox Code Playgroud)

结果约为600 ns.

如果我删除覆盖__hash____eq__方法,性能与默认对象的级别相同

有没有办法避免性能损失并仍然实现自定义哈希计算?

python lookup hash performance dictionary

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

标签 统计

hash ×2

python ×2

dictionary ×1

lookup ×1

performance ×1

python-3.x ×1

set ×1