“键”必须是不可变对象——如果书的目录名称会变化,那就不仅仅是眼花缭乱,而是手忙脚乱了。 “值”可以是 Python 中任何类型对象。 “值”可以重复。...: unhashable type: 'list' 出现了 TypeError 异常,特别注意看提示信息,告诉我们出问题的根源在于列表是 unhashable 类型。...简要说明: hash:翻译为“散列”或“哈希”,“hashable”意即“可散列”、“可哈希”。截止目前,已经学习过的 Python 内置对象中,数字、字符串、元组都是可散列的,也是不可变对象。...unhasable:翻译为“不可散列”、“不可哈希”,此前学过的列表和现在学习的字典,都是此类型的对象,同时为可变对象。 所以,字典也不能作为键值对的键。...老生常谈,既然字典类型的名称是 dict ,Python 的内置函数就会有 dict() 。
这是「AI 学习之路」的第 5 篇,「Python 学习」的第 5 篇 dict dict 是 Python 内置的字典类型,熟悉 Java 的同学可以把它类比为 Map。...通过散列函数求出的最终值就是对应的哈希值(Hash),Java 中的 Map 最常用的实现 HashMap 也是用类似的原理来设计的。...当然,散列函数本身比较复杂,还要牵扯到冲突的解决问题,简单来说,不同的 key 通过散列函数求得的内存位置可能是一样的,这样就导致了冲突,解决这种冲突的方法有很多,Python 设计者选择了开放定址法,...print(k, v) ... a 1 c 3 b 2 细心的同学一定发现了迭代的顺序和我们初始化定义的顺序是不同的,之前也提到了,dict 内部存放顺序是根据散列函数决定的,所以最后的存放顺序不一定和插入顺序一致...注意:key 必须是不可变对象(字符串,整数等),如果 key 是 list,就会报错 TypeError: unhashable type: 'list',tuple 虽然是不可变对象,但如果传入的
dict类型可以说是python里模块的命名空间,实例的属性,函数的关键字参数都有其的参与。...get items keys values MutableMapping __Setitem__ __defitem__ clear pop popitem setdefault update 只有可散列的数据类型才能做...只有实现了__hash__()和__eq__()方法的才能作为键 不可变的序列都可视为可散列的,但是 hash((1,2,3)) Out[1]: 2528502973977326415 hash((1,2...recent call last): File "", line 1, in hash((1,2,[2,3])) TypeError...,常用来方便用户继承 不可变映射类型,实际上可以理解为视图 MappingProxyType 集合:本质是许多唯一对象的聚集 交集&,并集|这些基本集合操作都有
对于这个问题,计划用两篇文章解释。这里先介绍Python语言中的可散列对象。 散列函数 在介绍散列表以及它在Python中的实现之前,先简要说明散列函数及其工作原理。...可散列类型 在Python内置的对象类型中,并非都是可散列的,只有那些不可变对象,比如整数、浮点数、字符串、元组等,才是可散列的。...如果要将hash()用于不可散列的对象,结果会出现TypeError异常,例如: >>> hash(["R","e","a","l","P","y","t","h","o","n"]) Traceback...前面提到,Python中的对象分为可散列和不可散列两种类型,而这里检测之后,所有内置对象类型都具有__hash__方法,是不是意味着都能用于hash()函数呢?前面说过可变对象是不可散列类型。...综上可知,对象是否可散列,主要看它的__hash__是什么,如果是None,则不可散列。
可散列的数据类型 在Python词汇表中,关于可散列类型的定义有这样一段话: “如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是不变的,而且这个对象需要实现__hash__()方法。...字典的键必须是可散列的,否则变来变去就找不到映射了。 于是可以得知原子不可变数据类型(str、bytes、和数值类型)都是可散列类型,frozenset冻结不可变集合,也是可散列的。...元组有两种情况,一、如果所有元素都是可散列的数据类型,那么元组是可散列的,二、如果元组里面的元素是其他可变类型的引用,那么元组是不可散列的,示例: >>> tt = (1, 2, (30, 40)) >...不可变映射类型 借助MappingProxyType,可以实现不可变字典。它返回的是一个只读的视图,会跟随源字典动态展示,但是无法对源字典做出改动。...散列表的键值,又称为散列值,Python中可以用hash()方法来计算所有内置类型对象的散列值。 自定义类型实际上调用的是自定义的__hash__。
标准库里所有映射类型都是利用 dict 来实现的,它们有个共同的限制,即只有可散列的数据类型才能用做这些映射里的键。 什么是可散列的数据类型?...如果两个可散列对象是相等的,那么它们的散列只一定是一样的根据这个定义,原子不可变类型(str,bytes和数值类型)都是可散列类型,frozenset 也是可散列的(因为根据其定义,frozenset...里只能容纳可散列类型),如果元组内都是可散列类型的话,元组也是可散列的(元组虽然是不可变类型,但如果它里面的元素是可变类型,这种元组也不能被认为是不可变的)。...一般来讲,用户自定义的类型的对象都是可散列的,散列值就是它们的 id() 函数的返回值,所以这些对象在比较的时候都是不相等的。...(如果一个对象实现了 __eq__ 方法,并且在方法中用到了这个对象的内部状态的话,那么只有当所有这些内部状态都是不可变的情况下,这个对象才是可散列的。)
起因是今天和一位刚刚面试完Python开发岗位的朋友交流,这个问题也是他在面试中遇到的问题: 怎么用一个简单的表达式合并Python中的两个Dict? 我相信很多人会质疑这个问题很需要解答吗?...module> TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items' 当然,我们真的想要实现的话,我们也可以强制转换...类似地,当值是不可散列的对象(例如列表)时,items()在Python 3(viewitems()在Python 2.7中)进行联合也将失败。...所以不要这样做: >>> c = dict(a.items() | b.items()) 我们演示一下值不可散列时会发生的情况: >>> x = {'a': []} >>> y = {'b': []}...字典旨在获取可散列的键(例如,frozenset或tuple),但是当键不是字符串时,此方法在Python 3中失败。
散列表是一种数据结构,它存储的是键值对(key-value)。 在散列表中,每个键值对的键必须是可散列的,这是因为存储的键值对通过使用其键的散列值进行索引。...当然,在真正的编程中,不需要自定义这种散列表对象,因为Python中的字典类型对象就能实现。...是因为在这个Python散列表中出现了散列碰撞。 使用Python标准库中的hash()函数计算散列值,出现碰撞是在所难免的。...如果键不是可散列的,Python会爆出TypeError异常。...>>> my_dict.clear() >>> sys.getsizeof(my_dict) 72 结论 本文主要介绍了Python散列表及其在字典对象类型中的具体应用,从而更深入了解了字典的特点。
可散列的类 3. 私有属性的利弊 4. `__slots__` 类属性节省空间 5....__format__ 为了解决该问题,在类中添加方法: def __format__(self, fmt_spec=""): components = (format(c, fmt_spec...可散列的类 hash(v1) # TypeError: unhashable type: 'Vector2D' 为了可以散列,需要实现__hash__(), __eq__() def __init..._Vector2D__x) # 100 print(v1) # (100., 4.0) 并不能真正的实现 私有和不可变 4....实例属性,类属性不受影响,但是实例属性会遮盖同名类属性 还可以订制类的数据属性: class anOtherVec(Vector2D): typecode = 'f' # 只是修改子类的数据类型
问题很多,而且也几乎是面试的时候会遇到的问题,基于此,理应秉承为自己负责的态度,提升自己的内功水平:) 解决问题之前 我们在推演答案之前不妨先想一下,如果我们自己构造一个dict会长成什么样?...设计哈希映射,这道题的目的在于完成映射关系的构建 通过解决这两个基本问题之后我们对于窥探dict的底层原理才有一点基本的认知。...即在python的字典中其内部使用的数据结构是哈希表 所谓哈希 哈希其实是音译的,其实就是hash,也是散列的意思,简单来说就是,通过这个散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,...构建散列函数的方法有很多,比如直接定址法、数字分析法、平方取中法、折叠法、随机数法、除留取余等。 这个话题其实也是一个大工程才能说明白,后续有机会再继续展开。...观察dict 我们先观察一个有趣的现象 [dict观察.png] 在这个案例中,作为字典的key值,要求选用不可变的容器如tuple,但如果选用可变的容器则是会弹出TypeError: unhashable
[columns_info_list]】 / 【Ⅷ. optional】列的元数据描述部分:列名,数据类型,列备注 表或者列的描述信息可以通过读取Oracle中元数据表格获取,或者TBLPROPERTIES...】【类的备注】 由于【列的数据格式】从Oracle中抽取,需要更改为与HIVE共有或兼容的格式,需要做以下的数据类型转换: timestamp => long , number => bigint |...dicimal ,other => String 将以上内容将通过oracal2Hive函数处理后以字典的格式返回 oracal2Hive # columnName 列名 # dataType 列的数据类型...']= f'decimal({dataScope}, {dataScale})' # 其他类型全部返回String类型 else: col_dict['columnType...dataType = col_info[1] # 获取表元素据-列的类型 dataScale = col_info[2] # 获取表元素据
散列表结构 字典与集合 散列表 散列表(Hash Table)结构是字典(Dictionary)和集合(Set)的一种实现方式。散列算法的作用是尽可能快地在数据结构中找到一个值。...使用散列表存储数据时,通过一个散列函数将键映射为一个数字,这个数字范围是0到列表长度。散列函数的选择依赖于键的数据类型,在此我们对键的hash值对数组长度区余的方法。散列表的数组究竟应该有多大?...这是编写散列函数时必须要考虑的。对散列表大小的限制,通常数组的长度应该是一个质数。...理想情况下,散列函数会将每个键值映射为唯一的数组索引,然而,键的数量是无限的,散列表的长度是有限的,一个理想的目标是让散列函数尽量将键均匀地映射到散列表中。...即使两个键散列后的值相同,依然被保存在同样的位置,只不过它们在第二个数组中的位置不一样罢了。 线性探查:当发生碰撞时,线性探测法检测散列表的下一个位置是否为空。
3) 数组的下标生成有重复,也就是说散列函数的结果不唯一,也叫散列值发生碰撞。 那如何规避掉以上问题? 答案是肯定的!...那接下来看图 4 里发现的最后一个问题,散列函数的选择。理论上来讲,对任何键值都有可能存在一个完美的散列函数并且不会发生任何碰撞,但是现实场景中找一个散列碰撞极少的散列函数就已经很优化了。....,1000000},有 100W 个元素,每个元素类型都为无符号整数,那这样,可以用最大值 1000000 来做基数取模,每个值的散列结果都唯一。但是这个得提前获知集合的大小以及类型。...2) 散列函数的效率 散列表能快速查找,归功于散列函数的快速计算,如果一个散列函数计算耗时很久,那对应的散列表查找也就不可能很快。...对上图中的散列表来说,不可能快速检索。不过可以考虑当链表到达一定的长度后,把链表变为一棵 AVL 树来加快检索效率。散列表的实现除了一般的拉链法还有比如开放地址法等,感兴趣的可以深入研究。
标准库里的所有映射类型都是利用 dict 来实现的,因此它们有个共同的限制,即只有可散列的数据类型才能用作这些映射里的键,本文记录Python 中 hash 相关内容。...这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。...也就是说,一个对象可散列,需要以下条件: 在这个对象的生命周期中,它 的散列值是不变的 实现 __hash__() 方 法 实现 __qe__() 方法 可散列的数据类型 原子不可变数据类型 image.png...dict的实现及其导致的结果 键必须是可散列的 一个可散列的对象必须满足以下要求。: 支持 hash() 函数,并且通过 __hash__() 方法所得到的散列 值是不变的。...另一方面,如 果一个含有自定义的 __eq__ 依赖的类处于可变的状态,那就 不要在这个类中实现 __hash__ 方法,因为它的实例是不可散 列的。
不可变序列:不可进行上述操作的序列,包括tuple, str, bytes等。 字典的变种 标准库里collections模块中提供了很多与字典类型相似的变种。...Counter: 这个映射类型会给键准备一个整数技术器,每次更行一个键的时候都会增加这个计数器,所以这个类型可以用来给散列表对象计数,或者当成多重集来用。...这就是 defaultdict , 它是 dict 的子类, 并实现了 missing 方法. dict的实现以及导致的结果 键必须是可散列的: 一个可散列的对象必须满足以下要求。...所有由用户自定义的对象默认都是可散列的,因为它们的散列值由 id() 来获取,而 且它们都是不相等的。 字典在内存上开销很大(用内存换效率)。...x += y vs x = x + y 对于一般不可变类型的变量来说这两个方法没啥区别,但对于可变类型如list(列表),dict(字典)就有区别了,x += y 就地改变了list的值,而x = x
Avro数据是采用一种与语言无关的模式进行描述。模式通常用json描述,序列化通常是二进制文件,不过通常也支持序列化为json。Avro假定模式在读写文件时出现,通常将模式嵌入文件本身。...Using Avro Records with Kafka Avro文件在数据文件中存储整个模式会造成适当的开销,与之不同的时,如果在每个记录中都存储模式文件的话,这样会造成每条记录的大小增加一倍以上。...如果key存在,且使用了默认的分区器,那么kafka将对该key进行散列(kafka 的broker内部自己实现的散列算法,当java升级时,其值不会改变)。使用散列结果将消息映射到特定的分区。...但是,kafka并没有限制你对分区进行自定义散列。有时候业务上也需要将数据进行不同的分区。假定你是一个B2B供应商,你最大的客户是一家称为banana的手持设备公司。...我们真正想要的是给banana用户一个单独的分区,然后其他用户按散列均分。
四、可变和不可变元素:可哈希和不可哈希 1.可变类型的数据不可进行哈希运算,不可变的数据类型可进行哈希运算 2.集合为什么无序? 3.散列类型为什么是无序的?...1.3 散列类型的存储过程 ? 散列类型的存储过程,图片来自网络 散列类型的意思就是无序的。 散列就是哈希。散列内部元素是无序的。...第三类,散列类型: 字典、集合。特征:内部元素是无序的。 4.为什么会出现散列冲突? 举个栗子: ?...四、可变和不可变元素:可哈希和不可哈希 1.可变类型的数据不可进行哈希运算,不可变的数据类型可进行哈希运算。 集合里面只能存储可哈希的对象。意思是集合里面只能存储不可变的数据类型。...因为散列表里面存储元素的时候是没有顺序的,散列表也是会不断变化的(会变化长度、调整元素位置的),所以说散列类型是无序的。 3.散列类型为什么是无序的?
元组的不可变在于其记录的内存地址不可变,而该地址中存储的内容是可以改变的(除非该地址中的内容本身也是不可变的)。...可用图表示如下: 字典的特征 通过以上对字典的实现原理的分析,不难得出以下结论: key 必须是可散列的。...键查询很快 dict 的实现是典型的空间换时间,只要字典能被装在内存里,就可以提供无视数据量大小的快速访问。...键的次序取决于添加顺序 当往 dict 里添加新键而又发生散列冲突的时候,新键可能会被安排存放到另一个位置。...扩容导致的结果就是要新建一个更大的散列表,并把字典里已有的元素添加到新表里。这个过程中可能会发生新的散列冲突,导致新散列表中键的次序变化。所以最好不要对字典同时进行迭代和修改。
Python 字典提供了散列查询的功能,使用灵活效率高,本文记录相关内容。...所以这个类型可以用来给可散列表对象计数,或 者是当成多重集来用——多重集合就是集合里的元素可以出现不止一 次。...就创造自定义映射类型来说,以 UserDict 为基类,总比以普通的 dict 为基类要来得方便。...更倾向于从 UserDict 而不是从 dict 继承的主要原因是,后者有时 会在某些方法的实现上走一些捷径,导致我们不得不在它的子类中重写 这些方法,但是 UserDict 就不会带来这些问题。...return str(key) in self.data def __setitem__(self, key, item): self.data[str(key)] = item 不可变映射类型
我们看下Hash中文定义:Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。...这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。...上面这两种再Hash是针对链表过长或者空间过于零散的场景设计的。如果把这些看明白了,那么Redis的Dict的实现思想也就大致清楚了。...key字段是一个无类型指针,我们可以让该key指向任意类型,从而支撑Dict的key是任意类型的能力。...一般一个dict只能承载一种类型的(key,value)对,而key和value的类型则可以是自定义的。这种开放的能力需要优良架构设计的支持。因为对类型没有约束,而框架自身无法得知这些类型的一些信息。