python學習筆記(四)——數據字典


                   數據字典

  字典(dictionary)是除列表之外python之中最靈活的內置數據結構類型。列表是有序的對象結合,字典是無序的對象集合。兩者之間的區別在於:字典當中的元素是通過鍵來存取的,而不是通過偏移存取,這個鍵可以是數字、字符串甚至元組。映射可以使用任何不可變對象標識元素,最常用的類型是字符串和元組,python唯一內建的映射類型是字典。

   創建和使用字典:

>>> phonebook={'Jason':'23453','James':'34231','Jzhou':'90798'}
>>> phonebook['Jason']
'23453'

   字典由多個鍵和其對應的值構成的對組成(鍵值對稱為項),上例中,姓名是鍵,分機號是值。每個鍵和它的值之間用冒號隔開,項之間用逗號隔開,整個字典用一對大括號括起來。

(注意:字典中的鍵是唯一的,其它映射也是如此,而值不唯一)

  dict函數

  dict函數可以通過其他映射(比如其他字典)或者(鍵、值)這樣的序列對建立字典

>>> items=[('name','Gumby'),('age',42)]
>>> d=dict (items )
>>> d
{'age': 42, 'name': 'Gumby'}
>>> d['name']
'Gumby'

  dict函數也可以通過關鍵字參數來創建字典

>>> d=dict(name='Jason',age=42)
>>> d
{'age': 42, 'name': 'Jason'}

  還能以映射作為dict函數的參數,以建立其項與映射相同的字典,如果不帶任何參數,則dict函數返回一個新的空的字典,就行list,tuple,str等函數一樣。如果另一個映射也是字典,可以使用字典方法copy(之后介紹)。

  基本的字典操作

    字典的基本行為在很多方面和序列類似:

  len(d)  返回d中項(鍵-值對)的數量

  d[k]返回關聯到鍵k上的值

  d[k]=v 將值v關聯到鍵k上

  del  d[k]刪除鍵為k的項

  k  in  d  檢查中是否有含有鍵為k的項

  字典也有一些自己的特性,如下:

   鍵類型:字典的鍵不一定為整型數據,也可能是其他不可變類型,如浮點型、字符串、元組等

   自動添加:即使那個鍵起初不存在於字典中,也可以分配給它一個值,即字典會建立一個新項;而列表在不使用append方法的前提下,不能將值關聯到列表之外的索引上

   成員資格:表達式k  in  d(d為字典)查找的是鍵而不是值;表達式 v  in l(l為列表)則用來查找值,而不是索引(另外,在字典中檢查鍵的成員資格比在列表中檢查值的成員更高效,尤其當數據結構的規模很大時。)

     我們來看一個簡單的例子,來看看字典相對於列表的好處:

>>> x=[]   #創建一個空列表
>>> x[42]='floor'    #出現錯誤

Traceback (most recent call last): File "<pyshell#77>", line 1, in <module>
    x[42]='floor'
IndexError: list assignment index out of range
>>> x={}   #創建一個字典
>>> x[42]='floor'   #自動將這項添加到字典中
>>> x    #字典的值
{42: 'floor'}
>>> 

    下面是一個較復雜的字典的示例:

# 使用人名作為鍵的字典,每個人用另一個字典來表示,phone和addr是子字典的鍵
people ={
     'Jason':{
        'phone':'2341',
        'addr':'Foo drive 23'
         },
     'James':{
        'phone':'4564',
        'addr':'Bar street 42'
         },
     'Jzhou':{
        'phone':'4564',
        'addr':'Baz avenue 90'
         }
    }

# 針對電話號碼和地址使用的描述性標簽會在打印輸出的時候用到
labels={
    'phone':'phone number',
    'addr':'address'
    }

name=raw_input('Name:')

# 查找電話號碼還是地址?使用正確的鍵
request=raw_input ("Phone number(p) or address(a)?")
# 使用正確的鍵:
if request=='p':key='phone'
if request=='a':key='addr'

# 如果名字是字典中的有效鍵才打印信息
if name in people:
    print "%s's %s is %s." % (name,labels[key],people[name][key])

raw_input("press any key to exit!")

 運行結果如下:

  

   字典的格式化字符串

  上一篇介紹過字符串是如何格式化的,現在我們來看看字典是如何格式化的。在每個轉換說明符的后面,加上鍵再跟其他說明元素。看例子:

>>> phonebook={'James':'3422','Jason':'3441','Jzhou':'2321'}
>>> phonebook
{'James': '3422', 'Jason': '3441', 'Jzhou': '2321'}
>>> "Jzhou's phone number is %(Jzhou)s." % phonebook
"Jzhou's phone number is 2321."

  除了增加字符串鍵之外,轉換說明符還是像以前一樣,當以這種方式使用字典的時候,只要所有給出的鍵都能在字典中找到,就可以獲得任意數量的轉換說明符,所以這類字符串格式化在模板系統中非常有用,看下面這個例子:

>>> template='''<html>
<head><title>%(title)s</title></head>
<body>
<h1>%(title)s<h1>
<p>%(text)s</p>
</body>'''
>>> data={'title':'my home page','text':'Welcome to my home age!'}

>>> print template % data
<html>
<head><title>my home page</title></head>
<body>
<h1>my home page<h1>
<p>Welcome to my home age!</p>
</body>

   字典方法

   clear——清除字典中的所有項。類似於list.sort,無返回值

>>> d={}
>>> d['name']='Jason'
>>> d['age']=42
>>> d
{'age': 42, 'name': 'Jason'}
>>> return_value=d.clear()
>>> d
{}
>>> print return_value
None

     通過下面的例子看一下clear的簡單作用:

#未使用clear方法
>>> x={}
>>> y=x
>>> x['key']='value'
>>> y
{'key': 'value'}
>>> x={}
>>> y    #x使用x={}置空后y的值還存在
{'key': 'value'}
#使用clear方法
>>> x={}
>>> y=x
>>> x['key']='value'
>>> y
{'key': 'value'}
>>> x.clear()  #x使用clear方法后,y的值也被清空了
>>> y
{}

  copy——返回一個具有相同鍵值對的新字典(實現的是淺復制,因為值本身相同,而不是副本)

>>> x={'username':'admin','machines':['foo','bar','baz']}
>>> y=x.copy()
>>> y['username']='mlh'
>>> y['machines'].remove ('bar')
>>> y
{'username': 'mlh', 'machines': ['foo', 'baz']}
>>> x
{'username': 'admin', 'machines': ['foo', 'baz']}

  上例看出,當在副本中替換值的時候,原字典不受影響,想上述y中username賦了新值,而x沒變;但是如果修改了某個值而不是替換,則原字典也會改變,像上述y的machines中移除了bar,則x中也移除了這個值。

  避免這個問題的方法是使用深復制(deep copy),復制它包含所有的值。使用copy模塊的deepcopy函數來完成

>>> from copy import deepcopy
>>> d={}
>>> d['names']=['James','Jason']
>>> c=d.copy()
>>> dc=deepcopy(d)
>>> d['names'].append('Jzhou')
>>> c
{'names': ['James', 'Jason', 'Jzhou']}
>>> dc
{'names': ['James', 'Jason']}

   fromkeys——使用給定的鍵建立新的字典,每個鍵默認對應的值為None

>>> {}.fromkeys(['name','age'])  #構造了有一個空字典來建立另外一個字典
{'age': None, 'name': None}

  也可以直接在所有字典的類型dict上調用方法

>>> dict.fromkeys(['name','age'])
{'age': None, 'name': None}

  若不想使用None作默認值,也可以提供自己的默認值

>>> dict.fromkeys(['name','age'],'Unknown')
{'age': 'Unknown', 'name': 'Unknown'}

    get——得到字典中的某個項

#一般當是視圖得到字典中不存在的項時將出錯
>>> d={}
>>> print d['name']

Traceback (most recent call last): File "<pyshell#42>", line 1, in <module>
    print d['name']
KeyError: 'name'
#使用get方法時不會出錯
>>> print d.get('name')
None
#也可以自定義默認值來替換'None'
>>> d.get('name','N/A')
'N/A'
#如果鍵值存在,get用起來就像普通的字典查詢一樣
>>> d['name']='Eric'
>>> d.get('name')
'Eric'

   看下面這個經過改造的例子:

people ={
     'Jason':{
        'phone':'2341',
        'addr':'Foo drive 23'
         },
     'James':{
        'phone':'4564',
        'addr':'Bar street 42'
         }
    }
labels={
    'phone':'phone number',
    'addr':'address'
    }
name = raw_input('Name:')
#查找電話號碼還是地址?
request=raw_input('phone number(p) or address(a)?')
#使用正確的鍵
key=request
if request =='p':key='phone'
if request =='a':key='addr'

person=people.get(name,{})
label=labels.get(key,key)
#使用get()提供的默認值
result=person.get('key','not available')

#如果請求不是p或者a,則使用get()提供的默認值
if request != 'p' and request != 'a':
  print "%s's %s is %s." % (name,label,result)
#如果請求正確,則按正常處理
elif request == 'p' or request == 'a':
  print "%s's %s is %s." % (name,labels[key],people[name][key])

raw_input("press any key to exit!")

  運行結果如下,即正常輸入和異常輸入時的處理結果:

   

   has_key——檢查字典中是否含有給出的鍵。表達式dict.has_key(k)相當於 表達式key  in  dict。注意在python3.0中不包含這個函數了。

>>> d={}
>>> d.has_key('name')
False
>>> d['name']='Jzhou'
>>> d.has_key('name')
True

   items和iteritems——items方法將所有字典項以列表方式返回,這些列表項中的每一項都來自於(鍵、值),但是在項返回時並沒有特殊順序。

>>> d={'title':'python','url':'http://www.python.org'}
>>> d.items ()
[('url', 'http://www.python.org'), ('title', 'python')]

iteritems作用大致一樣,但是會返回一個迭代器對象而不是列表

>>> it=d.iteritems ()
>>> it
<dictionary-itemiterator object at 0x01D9EAB0>
>>> list(it)  #將iterator轉換為列表
[('url', 'http://www.python.org'), ('title', 'python')]

         keys和iterkeys——keys方法將字典中的鍵以列表的形式返回,而iterkeys是返回針對鍵的迭代器

>>> d.keys()
['url', 'title']
>>> d.iterkeys()
<dictionary-keyiterator object at 0x02BD1DE0>
>>> list(d.iterkeys ())
['url', 'title']

      values和itervalues——values方法以列表的形式返回字典中的值,itervalues返回值的迭代器。與返回鍵的列表不同的是,返回值的列表中可以包含重復的元素

>>> d={}
>>> d[1]=1
>>> d[2]=2
>>> d[3]=3
>>> d[4]=1
>>> d.values()
[1, 2, 3, 1]
>>> d.itervalues ()
<dictionary-valueiterator object at 0x02BD1ED0>
>>> list(d.itervalues ())
[1, 2, 3, 1]

     pop——獲得對應於給定鍵的值,然后將這個鍵值對從字典中移除

>>> d={'x':1,'y':2}
>>> d.pop('x')
1
>>> d
{'y': 2}

    popitem——類似list.pop,后者會彈出列表的最后一個元素,但不同的是,popitem彈出的是隨機的項,因為字典是無序的。若想一個接一個的移除並處理項,這個方法非常有效,因為不用先獲取鍵的列表

>>> d={'title':'python','url':'http://www.python.org','spam':0}
>>> d
{'url': 'http://www.python.org', 'spam': 0, 'title': 'python'}
>>> d.popitem()
('url', 'http://www.python.org')
>>> d
{'spam': 0, 'title': 'python'}

盡管popitem和列表的pop方法很類似,但字典中並沒有與append等價的方法,因為字典是無序的,無“追加至最后”可言。

    setdefault——獲得與給定鍵相關聯的值,類似get()方法,另外,它還能在字典中不含有給定鍵的情況下設定相應的鍵值

>>> d={}
>>> d.setdefault('name','N/A')
'N/A'
>>> d
{'name': 'N/A'}
>>> d['name']='Jzhou'
>>> d.setdefault('name','N/A')
'Jzhou'
>>> d
{'name': 'Jzhou'}

可以看出,當鍵不存在的時候,setdefault返回默認值並且相應的更新字典。如果鍵存在,那么就返回與其對應的值,但不改變字典。默認值可選,如果不寫,默認為None

>>> d={}
>>> print d.setdefault('name')
None
>>> d
{'name': None}

    update——利用一個字典更新另外一個字典

>>> d={
    'title':'Python web site',
    'url':'http://www.python.org',
    'changed':'April 4 20:18 2013'
    }
>>> x={'title':'Python Language Website'}
>>> d.update(x) #提供的字典中的項會被添加到舊的字典中,若有相同的鍵則會進行覆蓋
>>> d
{'url': 'http://www.python.org', 'changed': 'April 4 20:18 2013', 'title': 'Python Language Website'}

    以上是字典常用的主要方法,調用方式和調用列表及字符串的方式相同。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM