gpt4 book ai didi

python - 在 IPython 中显示字典会重新计算哈希值

转载 作者:太空狗 更新时间:2023-10-30 02:55:50 26 4
gpt4 key购买 nike

奇怪的是,如果我在 IPython 中显示字典,它似乎会重新计算键的哈希值。这种行为不会发生在普通的 python 解释器中,我想知道这可能是什么原因。

一个例子:

class Fun(object):
def __init__(self, value):
self._value = value

def __hash__(self):
print('hashing')
return hash(self._value)

def __eq__(self, other):
if isinstance(other, Fun):
return self._value == other._value
else:
return self._value == other

def __repr__(self):
return '{}({})'.format(self.__class__.__name__, self._value)

创建字典时显然需要 hash:

In [2]: dict1 = {Fun(10): 5, Fun(11): 5}
hashing
hashing

但是当我稍后显示字典时,让我感到惊讶:

In [3]: dict1
Out[3]: hashing
hashing
{Fun(11): 5, Fun(10): 5}

如果我使用 repritems 就不会发生这种情况:

In [4]: dict1.items()
Out[4]: [(Fun(10), 5), (Fun(11), 5)]

In [5]: repr(dict1)
Out[5]: '{Fun(10): 5, Fun(11): 5}'

通常我不会在意,但我正在调查一个具有非常昂贵的 hash 方法的类的一些性能问题,我觉得为什么显示 dict1(特别反对 repr(dict1))应该重新计算键的 hash

但问题不仅仅是关于为什么(即使那是我真正感兴趣的),我也对如何禁用它非常感兴趣。我正在使用 IPython 5.1.0。

最佳答案

很有趣。我在散列函数中添加了一个 pdb.set_trace(),并尝试打印 dict1。进入 pdb 后,我使用“where”命令查看堆栈:

In [16]: dict1
Out[16]: > <ipython-input-14-01f77f64262f>(6)__hash__()
-> print('hashing')
(Pdb) where
/usr/local/virtualenvs/lab/bin/ipython(11)<module>()
-> sys.exit(start_ipython())
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/__init__.py(119)start_ipython()
-> return launch_new_instance(argv=argv, **kwargs)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/traitlets/config/application.py(596)launch_instance()
-> app.start()
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/terminal/ipapp.py(344)start()
-> self.shell.mainloop()
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/terminal/interactiveshell.py(550)mainloop()
-> self.interact(display_banner=display_banner)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/terminal/interactiveshell.py(674)interact()
-> self.run_cell(source_raw, store_history=True)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/interactiveshell.py(2723)run_cell()
-> interactivity=interactivity, compiler=compiler, result=result)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/interactiveshell.py(2831)run_ast_nodes()
-> if self.run_code(code, result):
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/interactiveshell.py(2885)run_code()
-> exec(code_obj, self.user_global_ns, self.user_ns)
<ipython-input-16-8239e7494a4a>(1)<module>()
-> dict1
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/displayhook.py(246)__call__()
-> format_dict, md_dict = self.compute_format_data(result)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/displayhook.py(152)compute_format_data()
-> return self.shell.display_formatter.format(result)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/formatters.py(177)format()
-> data = formatter(obj)
<decorator-gen-10>(2)__call__()
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/formatters.py(222)catch_format_error()
-> r = method(self, *args, **kwargs)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/core/formatters.py(699)__call__()
-> printer.pretty(obj)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/lib/pretty.py(368)pretty()
-> return self.type_pprinters[cls](obj, self, cycle)
/usr/local/virtualenvs/lab/lib/python2.7/site-packages/IPython/lib/pretty.py(623)inner()
-> p.pretty(obj[key])
> <ipython-input-14-01f77f64262f>(6)__hash__()
-> print('hashing')

看起来 ipython shell 正在努力漂亮地打印结果。漂亮的.py 代码是:

for idx, key in p._enumerate(keys):
if idx:
p.text(',')
p.breakable()
p.pretty(key)
p.text(': ')
p.pretty(obj[key])

查找 obj[key] 涉及再次散列 key 。

这可以避免吗?不确定! ¯\_(ツ)_/¯

关于python - 在 IPython 中显示字典会重新计算哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41413007/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com