1. 映射類型-字典python
1.0 數組
①字典是Python中惟一的映射類型,一般認爲是可變的哈希表tcp
②映射類型中的數據是無序排列的函數
③方法keys()、values()分別返回鍵、值組成的列表;items()方法能夠獲得鍵、值對應得元組組成的列表code
1.1 建立字典和給字典賦值server
①建立字典對象
>>> dict1 = {} >>> dict2 = {'name': 'earth', 'port': 80} >>> dict1, dict2 ({}, {'name': 'earth', 'port': 80}) >>> >>> # 使用內建方法 dict() 建立 >>> fdict = dict((['x', 1], ['y', 2])) >>> fdict {'y': 2, 'x': 1} >>> >>> #使用內建方法 fromkeys() 建立字典,字典中的元素具備相同的值,若未給出則默認爲'None' >>> ddict = {}.fromkeys(('x', 'y'), -1) >>> ddict {'y': -1, 'x': -1} >>> >>> edict = {}.fromkeys(('foo', 'bar')) >>> edict {'foo': None, 'bar': None}
1.2 訪問字典中的值ip
①經過循環查看鍵遍歷循環utf-8
>>> dict2 = {'name': 'earth', 'port': 80} >>> >>> for key in dict2.keys(): ... print 'key=%s, value=%s' % (key, dict2[key]) ... key=name, value=earth key=port, value=80
②直接迭代字典訪問每一個值rem
>>> dict2 = {'name': 'earth', 'port': 80} >>> >>> for key in dict2: ... print 'key=%s, value=%s' % (key, dict2[key]) ... key=name, value=earth key=port, value=80
③獲得字典中某元素的值
>>> # 相似序列類型 >>> dict2['name'] 'earth' >>> >>> print 'host %s is running on port %d' % \ ... (dict2['name'], dict2['port']) host earth is running on port 80
④訪問字典中沒有的數據/鍵,會返回'KeyError'錯誤
>>> dict2['server'] Traceback (most recent call last): file "<stdin>", line1, in <module> KeyError: 'server'
⑤檢查字典中是否有某個鍵能夠用字典的has_key()方法,或者'in'、'not in' 操做符。推薦使用'in'操做符
>>> 'sever' in dict2 False >>> dict2.has_key('sever') False >>> 'name' in dict2 # or dict2.has_key('server') True >>> dict2['name'] earth
⑥對字典賦值
>>> dict3 = {} >>> # 逐一添加 >>> dict3[1] = 'abc' >>> dict3['1'] = 3.14159 >>> dict3[3.2] = 'xyz' >>> dict3 {'1': 3.14159, 1: 'abc', 3.2: 'xyz'} >>> # 總體賦值 >>> dict3 = {1: 'abc', '1': 3.14, 2: 'xyz'} >>> dict3 {'1': 3.14, 1: 'abc', 2: 'xyz'}
⑦數字、字符串、元組等不可變對象可做爲字典的鍵,列表和其餘字典等可變對象不能做爲字典的鍵
1.3 更新字典
>>> dict2['name'] = 'venus' # 更新已有條目 >>> dict2['port'] = 6969 # 更新已有條目 >>> dict2['arch'] = 'sunos5' # 增長新條目 >>> >>> print 'host %(name)s is running on port %(port)d' %dict2 host venus is running on port 6969
注:①若字典中某鍵已存在,則[]更新已有的值;若不存在,則建立鍵、值
②字典中使用格式化字符串%的優勢是隻用一次字典的名字,而不是每一個元素都用元組參數表示
1.4 刪除字典元素和字典
>>> del dict2['name'] # 刪除鍵爲"name"的條目 >>> dict2.pop('port') # 刪除並返回鍵爲'port'的條目 6969 >>> dict2.clear() # 刪除dict2全部條目 >>> del dict2 # 刪除整個dict字典
2. 映射類型操做符
2.1 映射類型操做符
①字典的鍵查找操做符'[]'既能夠用於給鍵賦值;也能夠用於從字典中取值,取鍵對應的值
②'in'、'not in' 檢查某個鍵是否在字典中
3. 映射類型的內建函數和工廠函數
3.1 標準類型函數[type() str()]
①對字典調用type()方法,返回<type 'dict'>;調用str()返回字典的字符串表示
>>> dict3 = {1: 'abc', '1': 3.14, 2: 'xyz'} >>> type(dict3) <type 'dict'> >>> str(dict3) "{'1': 3.14, 1: 'abc', 2: 'xyz'}"
3.2 映射類型相關的函數
3.2.1 dict()
① dict()函數用來建立字典,若不提供參數,則生成空白字典;若給定的參數是可迭代的,則可迭代的元素必須成對出現,在每對中第一個元素是鍵,第二個元素是值
>>> dict(zip(('x', 'y'), (1, 2))) {'y': 2, 'x': 1} >>> dict([['x', 1], ['y', 2]]) {'y': 2, 'x': 1} >>> dict([('xy'[i-1], i) for i in range(1, 3)]) {'y': 2, 'x': 1}
②dict()能夠接受字典參數或者關鍵字參數組成的字典。對另一個字典對象調用dict()則會複製其內容生成新的字典,與字典內建方法copy()效果一致,更推薦使用copy()方法
>>> dict(x=1, y=2) {'y': 2, 'x': 1} >>> dict8 = dict(x=1, y=2) >>> dict8 {'y': 2, 'x': 1} >>> dict9 = dict(**dict8) # 更推薦使用 dict9 = dict8.copy() >>> dict9 {'y': 2, 'x': 1} >>> dict9 = dict8.copy() >>> dict9 {'y': 2, 'x': 1}
3.2.2 len()
對字典調用len()函數,會返回全部元素(鍵-值對)的數目
>>> dict2 = {'name': 'earth', 'port': 80} >>> dict2 {'name': 'earth', 'port': 80} >>> len(dict2) 2
3.2.3 hash()
將一個對象作爲參數傳遞給 hash() 會返回這個對象的哈希值,只有對象是可哈希的,纔可做爲字典的鍵。可哈希的對象返回的值是整型,不產生錯誤或異常;非可哈希類型傳遞給hash()會產生TypeError,使用這樣的鍵給字典賦值會產生TypeError 錯誤。
>>> hash([]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list' >>> >>> dict2[{}] = 'foo' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
3.2.4 合集
4. 映射類型內建方法
4.1 字典的內建方法
4.2 詳細講解
①字典的keys()方法返回一個列表,包含字典中全部的鍵;字典的values()方法返回一個列表,包含字典中全部的值;items()方法返回一個包含全部(鍵,值)元組的列表。這些方法均用於遍歷字典的鍵或值,且是無序的
>>> dict2 = {'name': 'earth', 'port': 80} >>> dict2.keys() ['name', 'port'] >>> >>> dict2.values() ['earth', 80] >>> >>> dict2.items() [('name', 'earth'), ('port', 80)] >>> >>> for eachkey in dict2.keys(): ... print 'dict2 key', eachkey, 'has value', dict2[eachkey] ... dict2 key name has value earth dict2 key port has value 80
②Python 2.4之後,字典新增sorted()內建函數,返回有序的迭代子,用來有序的迭代字典的鍵
>>> for eachkey in sorted(dict2): ... print 'dict2 key', eachkey, 'has value', dict2[eachkey] ... dict2 key name has value earth dict2 key port has value 80
③update()方法用來將一個字典A的內容添加到另外一個字典B中,字典B中的鍵若與A中的鍵重複,則B中該鍵對應的值會被A中相應的值替換,B中不存在的條目則從A中添加進去。clear()方法則用來刪除字典中全部條目
>>> dict2 = {'host': 'earth', 'port': 80} >>> dict3 = {'host': 'venus', 'server': 'http'} >>> dict2.update(dict3) >>> dict2 {'host': 'venus', 'port': 80, 'server': 'http'} >>> dict3.clear() >>> dict3 {}
④copy()返回一個淺複製的字典副本。get()方法相似於鍵查找操做符([]),不一樣在於在查找的鍵不存在時能夠給出一個參數做爲返回值,若未給出則返回None
>>> dict4 = dict2.copy() >>> dict4 {'host': 'venus', 'port': 80, 'server': 'http'} >>> dict4.get('host') 'venus' >>> dict4.get('xxx') >>> type(dict4.get('xxx')) <type 'NoneType'> >>> dict4.get('xxx', 'no such key') 'no such key'
⑤setdefault()方法檢查字典中是否有某鍵:如有,則返回所對應的值;若不存在該鍵,則對此鍵賦值並返回該值,且未提供第二個參數時默認賦值爲None
>>> myDict = {'host': 'earth', 'port': 80} >>> myDict.keys() ['host', 'port'] >>> myDict.items() [('host', 'earth'), ('port', 80)] >>> myDict.setdefault('port', 8070) 80 >>> myDict.setdefault('prot', 'tcp') 'tcp' >>> myDict.setdefault('prt') >>> myDict.items() [('prt', None), ('host', 'earth'), ('prot', 'tcp'), ('port', 80)]
⑥fromkeys()方法
>>> {}.fromkeys('xyz') {'y': None, 'x': None, 'z': None} >>> >>> {}.fromkeys(('love', 'honor'), True) {'love': True, 'honor': True}
5. 字典的鍵
5.1 不容許一個鍵對應多個值
每一個鍵只能對應一個項,對某鍵重複賦值時,取最近或者最後的賦值
>>> dict1 = {'foo': 789, 'foo': 'xyz'} >>> dict1 {'foo': 'xyz'} >>> >>> dict1['foo'] = 123 >>> dict1 {'foo': 123}
5.2 鍵必須是可哈希的
全部不可變對象都是可哈希的,均可以做爲字典的鍵;值相等的數字哈希值相同,表示他們是同一個鍵
5.3 例子
#!/usr/bin/env python # -*- coding:utf-8 -*- db = {} def newuser(): prompt = u'註冊賬號:' while True: name = raw_input(prompt.encode('gbk')) if name in db: prompt = u'賬號已被註冊,請更換一個:' continue else: break pwd = raw_input(u'輸入密碼:'.encode('gbk')) db[name] = pwd def olduser(): name = raw_input(u'登錄帳號:'.encode('gbk')) pwd = raw_input(u'登陸密碼:'.encode('gbk')) passwd = db.get(name) if passwd == pwd: print u'登陸成功,歡迎你',name else: print u"登陸失敗,賬號或密碼錯誤" def showmenu(): prompt = u""" (N)新用戶註冊 (E)已有帳戶登陸 (Q)退出 請輸入相應字母作出選擇:""" done = False while not done: chosen = False while not chosen: try: choice = raw_input(prompt.encode('gbk')).strip()[0].lower() except (EOFError, KeyboardInterrupt, IndexError): choice = 'q' print u'\n你選擇了:【%s】' % choice if choice not in 'neq': print u"輸入錯誤,請重試" else: chosen = True if choice == 'q': done = True if choice == 'n': newuser() if choice == 'e': olduser() if __name__ == '__main__': showmenu()
6. 集合
6.1 建立集合類型和給集合賦值
集合被建立的惟一方法是使用工廠方法set()和frozenset()
>>> s = set('cheeseshop') >>> s set(['c', 'e', 'h', 'o', 'p', 's']) >>> t = frozenset('bookshop') >>> t frozenset(['b', 'h', 'k', 'o', 'p', 's']) >>> type(s) <type 'set'> >>> type(t) <type 'frozenset'> >>> len(s) 6 >>> len(s) == len(t) True >>> s == t False
6.2 訪問集合中的值
能夠迭代遍歷查看集合中的成員,用 in 判斷某元素是不是集合成員
>>> 'k' in s False >>> 'k' in t True >>> 'c' not in t True >>> for i in s: ... print i ... c e h o p s
6.3 更新集合
>>> s.add('z') >>> s set(['c', 'e', 'h', 'o', 'p', 's', 'z']) >>> s.update('pypi') >>> s set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y', 'z']) >>> s.remove('z') >>> s set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y']) >>> s -= set('pypi') >>> s set(['c', 'e', 'h', 'o', 's']) >>> t.add('z') # 更新不可變集合,會引起異常 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'frozenset' object has no attribute 'add'
7. 集合類型操做符
7.1 集合類型操做符
①聯合(|)和集合的OR等價,其實就是集合的並集。等價於方法union()
>>> s | t set(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])
②交集(&)相似於集合的and,等價方法是 intersection()
>>> s & t set(['h', 's', 'o'])
③兩個集合(s、t)的差補或者相對補集是指存在一個集合c,該集合中的元素只屬於集合s,不屬於集合t。等價方法是difference()
>>> s - t set(['c', 'e'])
④兩個集合(s和t)的對稱差分是指存在一個集合C,該集合中的元素只屬於s或者t中的一個,而不能是二者的交集。等價方法是 symmetric_difference()
>>> s ^ t set(['b', 'e', 'k', 'c'])
⑤若操做符左右兩個集合的類型相同,都是可變集合或不可變集合,則產生的結果類型也是可變集合或不可變集合。若連個集合類型不一樣,則結果類型與操做符左邊的集合類型相同
>>> t | s frozenset(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's']) >>> t ^ s frozenset(['c', 'b', 'e', 'k']) >>> t - s frozenset(['k', 'b'])
⑥加號(+)不是集合類型操做符
>>> s + t Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'set' and 'frozenset'
7.2 僅用於可變集合的集合類型操做符
① |= 操做符和update()方法等價,用於向已存在的集合中添加成員
>>> s = set('cheeseshop') >>> u = frozenset(s) >>> s |= set('pypi') >>> s set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
② &= 操做符保留與新集合的交集,等價於 intersection_update() 方法
>>> s = set(u) >>> s &= set('shop') >>> s set(['h', 's', 'o', 'p'])
③ -= 操做's -= t'對s和t進行差更新,返回集合s去除集合t的元素後剩餘元素組成的集合,等價於difference_update()方法
>>> s = set(u) >>> s -= set('shop') >>> s set(['c', 'e'])
④ ^= 操做 's ^= t' 對s和t進行對稱差分更新,返回s和t的交集在s和t的並集中的補集,等價於symmetric_difference_update()方法
>>> s = set(u) >>> t = frozenset('bookshop') >>> s ^= t >>> s set(['c', 'b', 'e', 'k'])
8. 內建函數
8.1 標準類型函數
把集合做爲參數傳遞給內建函數len(), 返回集合的元素個數
>>> s = set(u) >>> s set(['p', 'c', 'e', 'h', 's', 'o']) >>> len(s) 6
8.2 集合類型工廠函數
set()和frozenset()分別用來生產可變集合和不可變集合。不提供參數默認生產空白集合;若提供參數,則參數必須是可迭代的,如序列、字典或文件等
>>> set() set([]) >>> set([]) set([]) >>> set(()) set([]) >>> set('shop') set(['h', 's', 'o', 'p']) >>> frozenset(['foo', 'bar']) frozenset(['foo', 'bar']) >>> >>> f = open('numbers', 'w') >>> for i in range(5): ... f.write('%d\n' % i) ... >>> f.close() >>> f = open('numbers', 'r') >>> set(f) set(['0\n', '3\n', '1\n', '4\n', '2\n']) >>> f.close()