<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 字典方法 跟前面所講述的其它數據類型類似,字典也有一些方法。通過這些方法,能夠實現對字典類型數據的操作。這回可不是屠龍之技的。這些方法在編程實踐中經常會用到。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#copy)copy 拷貝,這個漢語是copy的音譯,標準的漢語翻譯是“復制”。我還記得當初在學DOS的時候,那個老師說“拷貝”,搞得我暈頭轉向,他沒有說英文的“copy”發音,而是用標準漢語說“kao(三聲)bei(四聲)”,對于一直學習過英語、標準漢語和我家鄉方言的人來說,理解“拷貝”是有點困難的。誰知道在編程界用的是音譯呢。 在一般的理解中,copy就是將原來的東西再搞一份。但是,在python里面(乃至于很多編程語言中),copy可不是那么簡單的。 ~~~ >>> a = 5 >>> b = a >>> b 5 ~~~ 這樣做,是不是就得到了兩個5了呢?表面上看似乎是,但是,不要忘記我在前面反復提到的:**對象有類型,變量無類型**,正是因著這句話,變量其實是一個標簽。不妨請出法寶:`id()`,專門查看內存中對象編號 ~~~ >>> id(a) 139774080 >>> id(b) 139774080 ~~~ 果然,并沒有兩個5,就一個,只不過是貼了兩張標簽而已。這種現象普遍存在于python的多種數據類型中。其它的就不演示了,就僅看看dict類型。 ~~~ >>> ad = {"name":"qiwsir", "lang":"python"} >>> bd = ad >>> bd {'lang': 'python', 'name': 'qiwsir'} >>> id(ad) 3072239652L >>> id(bd) 3072239652L ~~~ 是的,驗證了。的確是一個對象貼了兩個標簽。這是用賦值的方式,實現的所謂“假裝拷貝”。那么如果用copy方法呢? ~~~ >>> cd = ad.copy() >>> cd {'lang': 'python', 'name': 'qiwsir'} >>> id(cd) 3072239788L ~~~ 果然不同,這次得到的cd是跟原來的ad不同的,它在內存中另辟了一個空間。如果我嘗試修改cd,就應該對原來的ad不會造成任何影響。 ~~~ >>> cd["name"] = "itdiffer.com" >>> cd {'lang': 'python', 'name': 'itdiffer.com'} >>> ad {'lang': 'python', 'name': 'qiwsir'} ~~~ 真的是那樣,跟推理一模一樣。所以,要理解了“變量”是對象的標簽,對象有類型而變量無類型,就能正確推斷出python能夠提供的結果。 ~~~ >>> bd {'lang': 'python', 'name': 'qiwsir'} >>> bd["name"] = "laoqi" >>> ad {'lang': 'python', 'name': 'laoqi'} >>> bd {'lang': 'python', 'name': 'laoqi'} ~~~ 這是又修改了bd所對應的“對象”,結果發現ad的“對象”也變了。 然而,事情沒有那么簡單,看下面的,要仔細點,否則就迷茫了。 ~~~ >>> x = {"name":"qiwsir", "lang":["python", "java", "c"]} >>> y = x.copy() >>> y {'lang': ['python', 'java', 'c'], 'name': 'qiwsir'} >>> id(x) 3072241012L >>> id(y) 3072241284L ~~~ y是從x拷貝過來的,兩個在內存中是不同的對象。 ~~~ >>> y["lang"].remove("c") ~~~ 為了便于理解,盡量使用短句子,避免用很長很長的復合句。在y所對應的dict對象中,鍵"lang"的值是一個列表,為['python', 'java', 'c'],這里用`remove()`這個列表方法刪除其中的一個元素"c"。刪除之后,這個列表變為:['python', 'java'] ~~~ >>> y {'lang': ['python', 'java'], 'name': 'qiwsir'} ~~~ 果然不出所料。那么,那個x所對應的字典中,這個列表變化了嗎?應該沒有變化。因為按照前面所講的,它是另外一個對象,兩個互不干擾。 ~~~ >>> x {'lang': ['python', 'java'], 'name': 'qiwsir'} ~~~ 是不是有點出乎意料呢?我沒有作弊哦。你如果不信,就按照操作自己在交互模式中試試,是不是能夠得到這個結果呢?這是為什么? 但是,如果要操作另外一個鍵值對: ~~~ >>> y["name"] = "laoqi" >>> y {'lang': ['python', 'java'], 'name': 'laoqi'} >>> x {'lang': ['python', 'java'], 'name': 'qiwsir'} ~~~ 前面所說的原理是有效的,為什么到值是列表的時候就不奏效了呢? 要破解這個迷局還得用`id()` ~~~ >>> id(x) 3072241012L >>> id(y) 3072241284L ~~~ x,y對應著兩個不同對象,的確如此。但這個對象(字典)是由兩個鍵值對組成的。其中一個鍵的值是列表。 ~~~ >>> id(x["lang"]) 3072243276L >>> id(y["lang"]) 3072243276L ~~~ 發現了這樣一個事實,列表是同一個對象。 但是,作為字符串為值得那個鍵值對,是分屬不同對象。 ~~~ >>> id(x["name"]) 3072245184L >>> id(y["name"]) 3072245408L ~~~ 這個事實,就說明了為什么修改一個列表,另外一個也跟著修改;而修改一個的字符串,另外一個不跟隨的原因了。 但是,似乎還沒有解開深層的原因。深層的原因,這跟python存儲的數據類型特點有關,python只存儲基本類型的數據,比如int,str,對于不是基礎類型的,比如剛才字典的值是列表,python不會在被復制的那個對象中重新存儲,而是用引用的方式,指向原來的值。如果讀者沒有明白這句話的意思,我就只能說點通俗的了(我本來不想說通俗的,裝著自己有學問),python在所執行的復制動作中,如果是基本類型的數據,就在內存中重新建個窩,如果不是基本類型的,就不新建窩了,而是用標簽引用原來的窩。這也好理解,如果比較簡單,隨便建立新窩簡單;但是,如果對象太復雜了,就別費勁了,還是引用一下原來的省事。(這么講有點忽悠了)。 所以,在編程語言中,把實現上面那種拷貝的方式稱之為“淺拷貝”。顧名思義,沒有解決深層次問題。言外之意,還有能夠解決深層次問題的方法嘍。 的確是,在python中,有一個“深拷貝”(deep copy)。不過,要用下一`import`來導入一個模塊。這個東西后面會講述,前面也遇到過了。 ~~~ >>> import copy >>> z = copy.deepcopy(x) >>> z {'lang': ['python', 'java'], 'name': 'qiwsir'} ~~~ 用`copy.deepcopy()`深拷貝了一個新的副本,看這個函數的名字就知道是深拷貝(deepcopy)。用上面用過的武器id()來勘察一番: ~~~ >>> id(x["lang"]) 3072243276L >>> id(z["lang"]) 3072245068L ~~~ 果然是另外一個“窩”,不是引用了。如果按照這個結果,修改其中一個列表中的元素,應該不影響另外一個了。 ~~~ >>> x {'lang': ['python', 'java'], 'name': 'qiwsir'} >>> x["lang"].remove("java") >>> x {'lang': ['python'], 'name': 'qiwsir'} >>> z {'lang': ['python', 'java'], 'name': 'qiwsir'} ~~~ 果然如此。再試試,才過癮呀。 ~~~ >>> x["lang"].append("c++") >>> x {'lang': ['python', 'c++'], 'name': 'qiwsir'} ~~~ 這就是所謂淺拷貝和深拷貝。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#clear)clear 在交互模式中,用help是一個很好的習慣 ~~~ >>> help(dict.clear) clear(...) D.clear() -> None. Remove all items from D. ~~~ 這是一個清空字典中所有元素的操作。 ~~~ >>> a = {"name":"qiwsir"} >>> a.clear() >>> a {} ~~~ 這就是`clear`的含義,將字典清空,得到的是“空”字典。這個上節說的`del`有著很大的區別。`del`是將字典刪除,內存中就沒有它了,不是為“空”。 ~~~ >>> del a >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined ~~~ 果然刪除了。 另外,如果要清空一個字典,還能夠使用`a = {}`這種方法,但這種方法本質是將變量a轉向了`{}`這個對象,那么原來的呢?原來的成為了斷線的風箏。這樣的東西在python中稱之為垃圾,而且python能夠自動的將這樣的垃圾回收。編程者就不用關心它了,反正python會處理了。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#getsetdefault)get,setdefault get的含義是: ~~~ get(...) D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. ~~~ 注意這個說明中,“if k in D”,就返回其值,否則...(等會再說)。 ~~~ >>> d {'lang': 'python'} >>> d.get("lang") 'python' ~~~ `dict.get()`就是要得到字典中某個鍵的值,不過,它不是那么“嚴厲”罷了。因為類似獲得字典中鍵的值得方法,上節已經有過,如`d['lang']`就能得到對應的值`"python"`,可是,如果要獲取的鍵不存在,如: ~~~ >>> print d.get("name") None >>> d["name"] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'name' ~~~ 這就是`dict.get()`和`dict['key']`的區別。 前面有一個半句話,如果鍵不在字典中,會返回None,這是一種情況。還可以這樣: ~~~ >>> d = {"lang":"python"} >>> newd = d.get("name",'qiwsir') >>> newd 'qiwsir' >>> d {'lang': 'python'} ~~~ 以`d.get("name",'qiwsir')`的方式,如果不能得到鍵"name"的值,就返回后面指定的值"qiwsir"。這就是文檔中那句話:`D[k] if k in D, else d.`的含義。這樣做,并沒有影響原來的字典。 另外一個跟get在功能上有相似地方的`D.setdefault(k)`,其含義是: ~~~ setdefault(...) D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D ~~~ 首先,它要執行`D.get(k,d)`,就跟前面一樣了,然后,進一步執行另外一個操作,如果鍵k不在字典中,就在字典中增加這個鍵值對。當然,如果有就沒有必要執行這一步了。 ~~~ >>> d {'lang': 'python'} >>> d.setdefault("lang") 'python' ~~~ 在字典中,有"lang"這個鍵,那么就返回它的值。 ~~~ >>> d.setdefault("name","qiwsir") 'qiwsir' >>> d {'lang': 'python', 'name': 'qiwsir'} ~~~ 沒有"name"這個鍵,于是返回`d.setdefault("name","qiwsir")`指定的值"qiwsir",并且將鍵值對`'name':"qiwsir"`添加到原來的字典中。 如果這樣操作: ~~~ >>> d.setdefault("web") ~~~ 什么也沒有返回嗎?不是,返回了,只不過沒有顯示出來,如果你用print就能看到了。因為這里返回的是一個None.不妨查看一下那個字典。 ~~~ >>> d {'lang': 'python', 'web': None, 'name': 'qiwsir'} ~~~ 是不是鍵"web"的值成為了None ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#itemsiteritems-keysiterkeys-valuesitervalues)items/iteritems, keys/iterkeys, values/itervalues 這個標題中列出的是三組dict的函數,并且這三組有相似的地方。在這里詳細講述第一組,其余兩組,我想憑借讀者的聰明智慧是不在話下的。 ~~~ >>> help(dict.items) items(...) D.items() -> list of D's (key, value) pairs, as 2-tuples ~~~ 這種方法是慣用的伎倆了,只要在交互模式中鼓搗一下,就能得到幫助信息。從中就知道`D.items()`能夠得到一個關于字典的列表,列表中的元素是由字典中的鍵和值組成的元組。例如: ~~~ >>> dd = {"name":"qiwsir", "lang":"python", "web":"www.itdiffer.com"} >>> dd_kv = dd.items() >>> dd_kv [('lang', 'python'), ('web', 'www.itdiffer.com'), ('name', 'qiwsir')] ~~~ 顯然,是有返回值的。這個操作,在后面要講到的循環中,將有很大的作用。 跟`items`類似的就是`iteritems`,看這個詞的特點,是由iter和items拼接而成的,后部分items就不用說了,肯定是在告訴我們,得到的結果跟`D.items()`的結果類似。是的,但是,還有一個iter是什么意思?在[《列表(2)](https://github.com/qiwsir/StarterLearningPython/blob/master/112.md)中,我提到了一個詞“iterable”,它的含義是“可迭代的”,這里的iter是指的名詞iterator的前部分,意思是“迭代器”。合起來,"iteritems"的含義就是: ~~~ iteritems(...) D.iteritems() -> an iterator over the (key, value) items of D ~~~ 你看,學習python不是什么難事,只要充分使用幫助文檔就好了。這里告訴我們,得到的是一個“迭代器”(關于什么是迭代器,以及相關的內容,后續會詳細講述),這個迭代器是關于“D.items()”的。看個例子就明白了。 ~~~ >>> dd {'lang': 'python', 'web': 'www.itdiffer.com', 'name': 'qiwsir'} >>> dd_iter = dd.iteritems() >>> type(dd_iter) <type 'dictionary-itemiterator'> >>> dd_iter <dictionary-itemiterator object at 0xb72b9a2c> >>> list(dd_iter) [('lang', 'python'), ('web', 'www.itdiffer.com'), ('name', 'qiwsir')] ~~~ 得到的dd_iter的類型,是一個'dictionary-itemiterator'類型,不過這種迭代器類型的數據不能直接輸出,必須用`list()`轉換一下,才能看到里面的真面目。 另外兩組,含義跟這個相似,只不過是得到key或者value。下面僅列舉一下例子,具體內容,讀者可以自行在交互模式中看文檔。 ~~~ >>> dd {'lang': 'python', 'web': 'www.itdiffer.com', 'name': 'qiwsir'} >>> dd.keys() ['lang', 'web', 'name'] >>> dd.values() ['python', 'www.itdiffer.com', 'qiwsir'] ~~~ 這里先交代一句,如果要實現對鍵值對或者鍵或者值的循環,用迭代器的效率會高一些。對這句話的理解,在后面會給大家進行詳細分析。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#pop-popitem)pop, popitem 在[《列表(3)》](https://github.com/qiwsir/StarterLearningPython/blob/master/113.md)中,有關于刪除列表中元素的函數`pop`和`remove`,這兩個的區別在于`list.remove(x)`用來刪除指定的元素,而`list.pop([i])`用于刪除指定索引的元素,如果不提供索引值,就默認刪除最后一個。 在字典中,也有刪除鍵值對的函數。 ~~~ pop(...) D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised ~~~ `D.pop(k[,d])`是以字典的鍵為參數,刪除指定鍵的鍵值對,當然,如果輸入對應的值也可以,那個是可選的。 ~~~ >>> dd {'lang': 'python', 'web': 'www.itdiffer.com', 'name': 'qiwsir'} >>> dd.pop("name") 'qiwsir' ~~~ 要刪除指定鍵"name",返回了其值"qiwsir"。這樣,在原字典中,“'name':'qiwsir'”這個鍵值對就被刪除了。 ~~~ >>> dd {'lang': 'python', 'web': 'www.itdiffer.com'} ~~~ 值得注意的是,pop函數中的參數是不能省略的,這跟列表中的那個pop有所不同。 ~~~ >>> dd.pop() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: pop expected at least 1 arguments, got 0 ~~~ 如果要刪除字典中沒有的鍵值對,也會報錯。 ~~~ >>> dd.pop("name") Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'name' ~~~ 有意思的是`D.popitem()`倒是跟`list.pop()`有相似之處,不用寫參數(list.pop是可以不寫參數),但是,`D.popitem()`不是刪除最后一個,前面已經交代過了,dict沒有順序,也就沒有最后和最先了,它是隨機刪除一個,并將所刪除的返回。 ~~~ popitem(...) D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty. ~~~ 如果字典是空的,就要報錯了 ~~~ >>> dd {'lang': 'python', 'web': 'www.itdiffer.com'} >>> dd.popitem() ('lang', 'python') >>> dd {'web': 'www.itdiffer.com'} ~~~ 成功地刪除了一對,注意是隨機的,不是刪除前面顯示的最后一個。并且返回了刪除的內容,返回的數據格式是tuple ~~~ >>> dd.popitems() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'dict' object has no attribute 'popitems' ~~~ 錯了?!注意看提示信息,沒有那個...,哦,果然錯了。注意是popitem,不要多了s,前面的`D.items()`中包含s,是復數形式,說明它能夠返回多個結果(多個元組組成的列表),而在`D.popitem()`中,一次只能隨機刪除一對鍵值對,并以一個元組的形式返回,所以,要單數形式,不能用復數形式了。 ~~~ >>> dd.popitem() ('web', 'www.itdiffer.com') >>> dd {} ~~~ 都刪了,現在那個字典成空的了。如果再刪,會怎么樣? ~~~ >>> dd.popitem() Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'popitem(): dictionary is empty' ~~~ 報錯信息中明確告知,字典已經是空的了,沒有再供刪的東西了。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#update)update `update()`,看名字就猜測到一二了,是不是更新字典內容呢?的確是。 ~~~ update(...) D.update([E, ]**F) -> None. Update D from dict/iterable E and F. If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k] ~~~ 不過,看樣子這個函數有點復雜。不要著急,通過實驗可以一點一點鼓搗明白的。 首先,這個函數沒有返回值,或者說返回值是None,它的作用就是更新字典。其參數可以是字典或者某種可迭代的數據類型。 ~~~ >>> d1 = {"lang":"python"} >>> d2 = {"song":"I dreamed a dream"} >>> d1.update(d2) >>> d1 {'lang': 'python', 'song': 'I dreamed a dream'} >>> d2 {'song': 'I dreamed a dream'} ~~~ 這樣就把字典d2更新入了d1那個字典,于是d1中就多了一些內容,把d2的內容包含進來了。d2當然還存在,并沒有受到影響。 還可以用下面的方法更新: ~~~ >>> d2 {'song': 'I dreamed a dream'} >>> d2.update([("name","qiwsir"), ("web","itdiffer.com")]) >>> d2 {'web': 'itdiffer.com', 'name': 'qiwsir', 'song': 'I dreamed a dream'} ~~~ 列表的元組是鍵值對。 ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md#has_key)has_key 這個函數的功能是判斷字典中是否存在某個鍵 ~~~ has_key(...) D.has_key(k) -> True if D has a key k, else False ~~~ 跟前一節中遇到的`k in D`類似。 ~~~ >>> d2 {'web': 'itdiffer.com', 'name': 'qiwsir', 'song': 'I dreamed a dream'} >>> d2.has_key("web") True >>> "web" in d2 True ~~~ 關于dict的函數,似乎不少。但是,不用著急,也不用擔心記不住,因為根本不需要記憶。只要會用搜索即可。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看