热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在python中实现hashtable/dictionary

如何解决《在python中实现hashtable/dictionary》经验,为你挑选了1个好方法。

我一直在研究python中的数据结构,我创建了一个简单的字典实现,如下所示.虽然这个实现最终没用(可能只是使用hash()而不是创建哈希函数等),但我对它们如何组合起来的细节感兴趣.

此实现选择起始大小11.记录self.capacity剩余的空闲时隙数.当添加(key,value)对时,它会减1,一旦它达到0,它就会在每次需要时触发一个新的槽.

我的问题是:从散列函数计算的散列值依赖于len(self.slots),但是当我向字典添加更多空间时,此值会不断增加.len(self.slots)我没有使用计算哈希函数,而是尝试使用初始大小(11),但是一旦字典尝试添加第12个(键,值)对,程序似乎就会卡住.这似乎表明散列函数需要基于表的大小,并且为了保持添加元素,我需要能够增加表的大小.这引出了以下问题.

    字典是否必须初始化为固定长度并保持这个长度?如果没有,添加元素时增加长度的首选方法是什么?

    如果字典的长度可以改变,是否应该在不使用字典大小的情况下构造散列函数?如何确保值仍然会减少到表槽位范围内的值而不减少通用模数表大小?

任何解释,有趣的见解或有用的花絮都将非常感激.

#

class HashTable:
    def __init__(self):
        self.size = 11
        self.capacity = self.size
        self.slots = [None] * self.size
        self.data =  [None] * self.size

    def hashfunction(self, key, size):
        return key%size

    def rehash(self, oldhash, size):
        return (oldhash+1)%size

    def put(self, key, value):
        hashvalue = self.hashfunction(key,len(self.slots))

        if self.capacity <1:
            self.slots += [None]
            self.data += [None]
            self.capacity += 1

        if self.slots[hashvalue] == None:
            self.slots[hashvalue] = key
            self.data[hashvalue] = value
            self.capacity -= 1
        else:
            if self.slots[hashvalue] == key:
                self.data[hashvalue] = data
            else:
                rehashed = self.rehash(hashvalue, len(self.slots))
                while self.slots[rehashed] != None and self.slots[rehashed] != key:
                    rehashed = self.rehash(rehashed, len(self.slots))
                if self.slots[rehashed] == None:
                    self.slots[rehashed] = key
                    self.data[rehashed] = value
                    self.capacity -= 1
                else:
                    self.data[rehashed] = value

    def get(self, key):
        startslot = self.hashfunction(key, len(self.slots))
        data = None
        found = False
        stop = False
        position = startslot
        while self.slots[position] != None and not found and not stop:
            if self.slots[position] == key:
                data = self.data[key]
                found = True
            else:
                position = self.rehash(position, len(self.slots))
                if position == startslot:
                    stop = True
        return data

    def __delitem__(self, key):
        hashvalue = self.hashfunction(key, len(self.slots))

        if self.slots[hashvalue] == key:
            self.slots[hashvalue] = None
            self.data[hashvalue] = None
        else:
            rehashed = self.hashfunction(hashvalue, len(self.slots))
            while self.slots[rehashed] != key:
                rehashed = self.hashfunction(rehashed, len(self.slots))
            if self.slots[rehashed] == key:
                self.slots[rehashed] == None
                self.data[rehashed] == None

    def __contains__(self, key):
        return key in self.slots

    def __getitem__(self, key):
        return self.get(key)

    def __setitem__(self, key, value):
        self.put(key, value)

Martijn Piet.. 6

您需要将哈希和表格大小分开.哈希应仅基于密钥,而不是大小.每个键值条目存储以下信息:

钥匙

哈希 - 从密钥派生的常量值.确保它有呼吸以避免太多碰撞.

价值

您根据表大小和哈希选择一个插槽:

slot = hash % tablesize

然后,当您当前表中的空间不足时,生成一个表(比如,大小增加一倍),以适应您不断增长的数据集,并重新绘制所有内容.您已经缓存了哈希值,您需要做的就是获取每个(key, hash, value)元组并使用上面的公式重新计算新的槽,现在使用更大的表格.

你还必须决定如何处理碰撞 ; 给出当前表大小的两个哈希最终在同一个槽中.Python dict使用开放式寻址,其中哈希以可重现的方式被"扰乱",直到找到另一个空槽.

您可能希望研究Python dict源代码以了解它们是如何执行此操作的,请参阅有关如何处理冲突的详尽注释.您还可以观看此PyCon演示文稿,其中Brandon Rhodes使用一些非常有启发性的图形解释所有这些细节.或者你可以拿起一本美丽的代码,其中有一章关于Python的dict实现.



1> Martijn Piet..:

您需要将哈希和表格大小分开.哈希应仅基于密钥,而不是大小.每个键值条目存储以下信息:

钥匙

哈希 - 从密钥派生的常量值.确保它有呼吸以避免太多碰撞.

价值

您根据表大小和哈希选择一个插槽:

slot = hash % tablesize

然后,当您当前表中的空间不足时,生成一个表(比如,大小增加一倍),以适应您不断增长的数据集,并重新绘制所有内容.您已经缓存了哈希值,您需要做的就是获取每个(key, hash, value)元组并使用上面的公式重新计算新的槽,现在使用更大的表格.

你还必须决定如何处理碰撞 ; 给出当前表大小的两个哈希最终在同一个槽中.Python dict使用开放式寻址,其中哈希以可重现的方式被"扰乱",直到找到另一个空槽.

您可能希望研究Python dict源代码以了解它们是如何执行此操作的,请参阅有关如何处理冲突的详尽注释.您还可以观看此PyCon演示文稿,其中Brandon Rhodes使用一些非常有启发性的图形解释所有这些细节.或者你可以拿起一本美丽的代码,其中有一章关于Python的dict实现.


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 一、HashMap1.HashMap概述:HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是 ... [详细]
  • 要讨论这些常用的默认初始容量和扩容的原因是:当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复 ... [详细]
  • HashMap和Hashtable的区别主要的区别有三点:线程安全性,同步(synchronization),以及速度。(两者都是无序排放)HashMap几乎可以等价于Hashtable,除了Hash ... [详细]
  • 常用API-Hashtable类及其与HashMap、HashSet的区别转载请表明出处:http:blog.csdn.netu012637501(嵌入式_小J的天空)一、Hashtable&l ... [详细]
  • 用户购买商品时if(e.CommandName.ToLower()"buy"){判断用户购物车是否为空如果为空则分配 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • hashmap线程不安全允许有null的键和值效率高一点、方法不是Synchronize的要提供外同步有containsvalue和containsKey方法HashMap是Java1 ... [详细]
  • HashMap及HashTable源码解析HashMap在java和Android经常使用到,之前学过数据结构,理解了它的原理,却很 ... [详细]
author-avatar
金瑞期货秦臻
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有