先把各种类型的属性做个对比(自己整理)



是否可修改-hash

(不可修改才可index)

是否有序

是否有重复

是否可下标

(可查找)

备注 

tuple

index-value/obj

不可修改(可hash)

有序

可有重复



str


不可修改(可hash)

有序

可有重复


特别的list

list

index-value/obj

可修改

有序

可有重复



dict

key:value

可修改

无序

key无重复


虽然无序,但是有key可查找

set

key

不可修改

无序

无重复

不可

无value的dict

int

 

不可修改

有序

可有重复

不可

 

float

 

不可修改

有序

可有重复

不可

 

 

 

 

 

 

 

 

一句话总结

是否可修改/hash

  • 不能修改的数据类型
  •          不可修改:immutable 
  •          可hash:hashable
  •          不可修改的==可hash==能做为index / key
  •          具体包括: int, float, string,tuple
  • 可以修改的数据类型
  •          可修改:mutable 
  •          不可hash:inhashable
  •          可修改的==不可hash== 不能做为index / key
  •          具体包括:list,dict,set

是否可下标subscript able

  • 有index /key的就是可下标的
  • 可下标就可以查找
  •  

是否可嵌套 nest able

  • 有index /key的就是可下标的 subscript,就是可嵌套的

 

哪些数据类型可以嵌套(要看是key的嵌套,还是obj的嵌套)

总结:可修改==不可做index/key,可下标==有index/key==可查找

(1) 各种数据类型,包括数据类型的 index / key (一定不可变) 和value(有的可变 / 有的不可变)

          如果是不可变的(可hash),那么只能是 int,float,string,tuple等(不能是list dict)

         如果是可变的,可以是各种类型

        所以dictA1={[ ]:"jack"}  肯定错误

(2)如果这一层想通过下标查找

 这一层如果是可变类型(list 或 dict)或例外 tuple  string,那么这一层一定可以  [ ] 这样查找

          或者说是,可下标的(list,dict,tuple,string 没例外),那么这一层一定可以  [ ] 这样查找 

          或者说是,有index/key(list,dict,tuple,string 没例外),那么这一层一定可以  [ ] 这样查找 

(3)如果想通过最外层,想通过 嵌套下标 查找

 这多层,每层都必须是可变类型(list 或 dict)或例外 tuple string,那么这多层嵌套可以  [ ] 这样查找 

        或者说是,这多层都是可下标的(list,dict,tuple,string 没例外),那么这多层嵌套可以  [ ] 这样查找  

       或者说是,这多层都有index/key(list,dict,tuple,string 没例外),那么这多层嵌套可以  [ ] 这样查找  

 

详细的内容

(1)支持下标的类型:tuple ,list  ,dict, string  (有序index或者有key 就支持下标)

(2)不支持下标的类型:set,int ,float 和各种数字类型

(3)list

        list的元素可变,所以可以是任何类型

(4)dict

        dict的key的嵌套,因为key不可变

              只支持可hash类型:int, float, string ,tuple, 不支持可变的 list ,dict ,set类型

        dict的value嵌套,因为value可变

              所有类型都可以

             但set 等类型还是无法使用下标

(5)set的用法   set={value/obj   ,  value/obj }  

         set 不支持使用 index (肯定也不支持 key),set 里只有一堆 value/obj

         set的元素,需要可hash,只支持 int,float ,string,tuple

        同理,string ,int ,float set 因为本身不可修改,元素也是不可修改的

       所以也只能是 对应string ,int float  tuple  等,不能是 可变类型,list,dict,

   一个数据类型,本身不可变 (可hash),那么这个数据类型的元素也不可变

      但是特列是tuple,他的元素可以是可变的 list,dict

 

string的嵌套

虽然string 嵌套没什么意义,但好像这样也算嵌套的。

>>> strC="[1,3,4]aabnb{8,9}"
>>> strC
'[1,3,4]aabnb{8,9}'

>>> strD="abc"'12345'
>>> strD
'abc12345'

 

 

LIST嵌套和使用下标

(1)  list里的 元素obj 可以是各种类型:

     list,tuple,dict,set,string,int,float 等等

(2)  list 的 允许嵌套和使用下标,只能是  list, tuple,dict,string

     list[ list, tuple,dict]

(3) 如果是string,int,肯定不能往下嵌套了,但是set 也是不能的

     而且set int float一样,是不支持 index的

 

嵌套后支持index的(伪命题,哪一层可下标index得看哪一层本身是否支持)

>>> listB1=[{"name":"jack","age":"15"},{"name":"john","age":"16"}]
 >>> listB1[0]["name"]
 'jack'
 >>> listB1=[("a",1),("b",2)]
 >>> listB1[1][1]
 2
 >>> listB1=[["a",11],["b",22]]
 >>> listB1[0][1]
 11>>> listC1=["abcde","hhh"]
 >>> listC1[0][3]
 'd'

 

嵌套后不支持index的(伪命题,哪一层可下标index得看哪一层本身是否支持)

>>> listB1=[{"apple","pear"},{"red"},{"blue"}]
 >>> listB1[0][1]
 Traceback (most recent call last):
   File "<pyshell#51>", line 1, in <module>
     listB1[0][1]
 TypeError: 'set' object does not support indexing
 >>> >>> listB1=["str1","str2","str3"]
 >>> listB2=[11,2,3]

 

tuple嵌套和使用下标

嵌套后支持index的,同list

>>> tupleA1=((1,2,3),4,5,6)
 >>> tupleA1[0][2]
 3
 >>> tupleA2=(["a","b"],["c"])
 >>> tupleA2[0][1]
 'b'
 >>> tupleA3=({"name":"jack"},{"class":1})
 >>> tupleA3[1]["class"]
 1

 

嵌套后不支持index的,还是set 和  int等

>>> tupleA4=({"a","b"},{"aaa"})
>>> tupleA4[0]
 {'b', 'a'}
 >>> tupleA4[1]
 {'aaa'}
 >>> tupleA4[0][0]
 Traceback (most recent call last):
   File "<pyshell#65>", line 1, in <module>
     tupleA4[0][0]
 TypeError: 'set' object does not support indexing

 

dict嵌套和使用下标

dict的key的限制

python不支持dict的key为list,dict,set类型,因为list和dict类型是unhashable(不可哈希)的

只支持key是tuple的

>>> dictA1={{"name":"jack","name":"john"}:{"math":90,"phy":95}}
 Traceback (most recent call last):
   File "<pyshell#67>", line 1, in <module>
     dictA1={{"name":"jack","name":"john"}:{"math":90,"phy":95}}
 TypeError: unhashable type: 'dict'
 >>> dictA2={[1,2,3]:[4,5,6]}
 Traceback (most recent call last):
   File "<pyshell#68>", line 1, in <module>
     dictA2={[1,2,3]:[4,5,6]}
 TypeError: unhashable type: 'list'>>> dictA4={{1,2,3}:{7,8,9}}
 Traceback (most recent call last):
   File "<pyshell#74>", line 1, in <module>
     dictA4={{1,2,3}:{7,8,9}}
 TypeError: unhashable type: 'set'

只有tuple,string,int,float可以作为key

>>> dictA3={(1,2,3):(4,5,6)}
 >>> dictA3[(1,2,3)][1]
 5

 

dict的value的限制

>>> dictB1={"aa":{"a":1,"b":2},"bb":11}   #value可以是dict,可以下标查
 >>> dictB1["bb"]
 11
 >>> dictB1["aa"]["a"]
 1

 >>> dictB2={"aa":[1,2,3],"bb":11}            #value可以是list,可以下标查
           
 >>> dictB2["aa"][2]
           
 3

 >>> dictB3={(1,2,3):(11,12,13),"bb":11}     #key可以是tuple ,value可以是tuple,可以下标查
           
 >>> dictB3[(1,2,3)][1]
           
 12

 

嵌套后不支持index的

>>> dictB4={"aa":{11,12,13},"bb":11}      #value可以是set, 但是不可以下标查
           
 >>> dictB4["aa"][0]
           
 Traceback (most recent call last):
   File "<pyshell#85>", line 1, in <module>
     dictB4["aa"][0]
 TypeError: 'set' object does not support indexing
 >>>

 

set嵌套和--set本身无下标

(1) set 没有下标index

(2)set的 value/obj  还不能是list ,dict ,set等不能hash的类型

        也就是说,set 一般元素使用  string,int,float 等,不能嵌套

(3)set唯一可嵌套的,tuple

        但是仍然无法有下标,和查找

set无法嵌套 list dict

>>> setA={[1,2,3],[6,5,4]}
           
 Traceback (most recent call last):
   File "<pyshell#86>", line 1, in <module>
     setA={[1,2,3],[6,5,4]}
 TypeError: unhashable type: 'list'>>> setA={{"a":1,"b":2},"aaa"}
Traceback (most recent call last):
   File "<pyshell#91>", line 1, in <module>
     setA={{"a":1,"b":2},"aaa"}
 TypeError: unhashable type: 'dict'
 >>>

 

SET只能嵌套 tuple( 其实就是 set的元素只能是 int float string tuple等)

>>> setA={(1,2,3),(6,5,4)}
           
 >>> setA[1][1]
           
 Traceback (most recent call last):
   File "<pyshell#88>", line 1, in <module>
     setA[1][1]
 TypeError: 'set' object does not support indexing
 >>> setA[(1,2,3)][1]
           
 Traceback (most recent call last):
   File "<pyshell#89>", line 1, in <module>
     setA[(1,2,3)][1]
 TypeError: 'set' object is not subscriptable

 

python里 什么叫不可哈希(可变的不可hash)

作者:三十六_
链接:https://www.jianshu.com/p/bc5195c8c9cb

一个对象能被称为 hashable , 它必须有个 hash 值,这个值在整个生命周期都不会变化,而且必须可以进行相等比较,所以一个对象可哈希,它必须实现__hash__() 与 __eq__() 方法。

Python 的某些链接库在内部需要使用hash值,例如往集合中添加对象时会用__hash__() 方法来获取hash值,看它是否与集合中现有对象的hash值相同,如果相同则会舍去不加入,如果不同,则使用__eq__() 方法比较是否相等,以确定是否需要加入其中。

对于 Python 的内建类型来说,只要是创建之后无法修改的(immutable)类型都是 hashable 如字符串,可变动的都是 unhashable的比如:列表、字典、集合,他们在改变值的同时却没有改变id,无法由地址定位值的唯一性,因而无法哈希我们自定义的类的实例对象默认也是可哈希的(hashable),而hash值也就是它们的id()。

 

是否可修改  immutable == hashable ?

   immutable:

    创建后无法修改的数据类型(obj)都是 hashable的

    自定义的类,new实例对象默认也是可哈希的(hashable),而hash值也就是它们的id()。

    创建后可修改的数据类型(obj)都是 unhashable的

      一个对象能被称为 hashable , 它必须有个 hash 值,这个值在整个生命周期都不会变化,而且必须可以进行相等比较,所以一个对象可哈希,它必须实现__hash__() 与 __eq__() 方法。

      列表、字典、集合,他们在改变值的同时却没有改变id,无法由地址定位值的唯一性,因而无法哈希