python可hash型別和不可hash型別

2021-10-06 19:24:02 字數 2105 閱讀 4743

最近在寫**的時候發現了乙個問題:我有一系列的元組(實際上是強化學習的state和action),它們要作為字典的鍵,而值是reward,我以前一直認為只有字串才能作為鍵,然後就用str()函式將元組轉化成string型別,後來要畫圖,又要得到字典的鍵,得到的是帶有元組括號的一些雜七雜八的東西。。。

後來才想起來不可變型別都是可雜湊的,都可以作為鍵。。。

然後就好好的寫一下這個可hash背後原因,因為資料結構雜湊定址法忘了好多。

python是動態型別語言,它在初始變數時不需要宣告型別。還有乙個特點:在python中變數儲存的機制是完全不一樣的,當給乙個變數賦值時首先直譯器會給這個值分配記憶體空間,然後將變數指向這個值的位址,那麼當我們改變變數值的時候直譯器又會給新的值分配另乙個記憶體空間,再將變數指向這個新值的位址,所以和c語言相比,在python中改變的是變數所指向的位址,而記憶體空間中的值是固定不變的。

對於不可變型別,如整數,字串,元組等,如果兩個變數值相同,那麼這2個變數指向相同記憶體;如下

i =

5print

"i ---> "

,iprint

"id(i) ---> "

,hex(id

(i))

j =5

print

"j ---> "

,jprint

"id(j) ---> "

,hex(id

(j))

結果:i ---

>5id

(i)---

>

0xa26f880

j --

->5id

(i)---

>

0xa26f880

可以看到i和j指向相同的位址

然而當在i上進行操作時,位址會變化,相當於先計算生成這個新的數值,並為該值分配新的記憶體,然後剛才的i會指向這個新的值,所以記憶體發生變化,而前面那個引用會根據引用計數機制或者其他gc機制自動**:如下

i +=

1print

"i ---> "

,iprint

"id(i) ---> "

,hex(id

(i))

結果:i ---

>6id

(i)---

>

0xa26f874

原來是: 0xa26f880

重點來了,以上僅僅是對於不可變型別,而對於可變型別呢?

如列表:

i =[1

,2,3

]print

"i ---> "

,iprint

"id(i) ---> "

,hex(id

(i)) 4

)print

"i ---> "

,iprint

"id(i) ---> "

,hex(id

(i))

j =[1.5

,2.5

,3.5

]print

"j ---> "

,jprint

"id(j) ---> "

,hex(id

(j))

k =[1.5

,2.5

,3.5

]print

"k ---> "

,jprint

"id(k) ---> "

,hex(id

(k))

結果:i ---

>[1

,2,3

]id(i)---

> 0xb73fa1acl

i --

->[1

,2,3

,4]id

(i)---

> 0xb73fa1acl

j --

->

[1.5

,2.5

,3.5]id

(j)---

> 0xb6fed06cl

k --

->

[1.5

,2.5

,3.5]id

(k)---

> 0xb6fed04cl

可空型別 ?和??

可空型別可以表示所有實際型別的值加上null。如果和資料庫打交道,這就會很有用,因為在資料庫表中遇到未定義的列是很常見的事情。為了定義乙個可空變數型別,應在底層資料型別中新增問號 作為字尾。注意,這種語法只對值型別是合法的,區域性可空變數必須賦值乙個初始值。定義一些區域性可空型別 int?a 10 ...

可擴充套件性的hash演算法和系統

hash演算法是計算機系統非常重要的演算法,它的目的就是要將任意型別的資訊均勻影射到乙個有限的連續空間上 它的用途可以用於資料的快速檢索 比如hashmap 也可以用於資料簽名 比如md5 也可用於安全系統 sha 也普遍用於p2p系統中的資訊檢索和路由 本文中提到的應用著重指資料檢索中使用的has...

C 可空型別 和 語法

public void getinfo int?pagesize int?代表 pagesize 可以為null pagesize pagesize 2 上面這一行 和如下 等同,它的意思就是pagesize為null嗎,如果是就返回2,如果不是就返回pagesize pagesize pagesi...