我正在尝试为我将散列到字典中的某个对象创建自定义散列函数。散列函数是唯一的(不是标准的 Python 函数)。这对我来说非常重要:使用独特的功能。每个键的值都是一个列表。
假设我重写了 __hash__ 并最终得到了对象的正确哈希值。会:
dict = {}
dict[number_here] = value
将值散列到位置编号 number_here 中,还是它仍然位于 Python 的散列表将为该数字计算的位置?
打印 dict 只显示项目而不是它们所在的位置。但是,当我执行 hash(4) 时,结果是 4。所以我假设这意味着整数被散列到它们各自的位置?
如果我错了,有人可以验证我的发现或向我解释吗?
最佳答案
python dict 实现使用散列值来基于键稀疏地存储值并避免在该存储中发生冲突。它使用 hash() 的结果作为起点,它不是最终位置。
因此,尽管 hash(4) 返回 4,但底层 C 结构中的确切“位置”也基于其他键已经存在,以及当前表有多大。例如,python 哈希表会根据需要调整大小(添加项目)。
由于 dict 没有顺序,这不是您需要担心的事情,也不希望影响它。如果您需要在字典中排序,请改用 collections.OrderedDict() 实现,它会单独跟踪排序。
您可能想阅读哈希表如何在 Wikipedia 上工作; Python 在其实现中使用开放寻址。
在表中选择槽时,取哈希值(整数)与当前表大小的模,因此在大小为32的表上,所以键45,hash值 45 最初将存储在插槽 14 中。
如果发生冲突(插槽 14 中已经存储了其他内容,并且不是整数 45),则插槽值扰动直到出现空插槽找到或找到相同的 key 。扰动是用公式完成的:
perturb = slot = hash
while slot_is_full and item_in_slot_is_not_equal_to_key:
slot = (5*slot) + 1 + perturb
perturb >>= 5
因此,当发生冲突时,会以逐渐变小的步长选择另一个插槽,直到它扫描整个表格。请注意,如果需要,表格已经调整大小以腾出空间。
为了使其正常工作,自定义类型需要 __hash__()方法和需要实现__eq__()以确定两个实例是否代表相同的键。匹配哈希值是不够的。要让 dict 实现考虑两个实例来表示完全相同的键,它们的哈希值必须匹配,并且它们必须为 == 相等运算符返回 True。这些对象被认为是 hashable .
(对于 Python 2.x,实现 __cmp__() hook 可以代替实现 __eq__();在 Python 3 中已删除对此的支持)。
关于python - 在字典中覆盖 Python 的哈希函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13514716/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI