7.1 映射类型:字典
字典是Python语言中唯一的映射类型,映射类型对象里哈希值(键)和指向的对象(值)是一对多的关系,字典对象可变,它是一个容器类型,能存储任意个Python对象
注:什么是哈希表?
哈希表是一种数据结构:哈希表中存储的每一条数据,叫做一个值(value),是根据与它相关的一个键(key)的数据项进行存储的,键和值合在一起呗称为"键-值 对"
哈希表的算法是获取键,对键执行一个叫做哈希函数的操作,并根据计算结果,在数据结构的某个地址来存储你的值
如何创建字典和给字典赋值:
>>> 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()创建一个默认字典
>>> ddict = {}.fromkeys(('x','y'),-1)
>>> ddict
{'y': -1, 'x': -1}
>>> edict = {}.fromkeys(('foo','bar'))
>>> edict
{'foo': None, 'bar': None}
如何访问字典中的值:
>>> 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
>>> 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
检查字典中是否有某个键的方法 has_key()或in,not in
>>> 'name' in dict2
True
>>> 'server' in dict2
False
>>> 'name' in dict2
True
>>> dict2['name']
'earth'
>>> dict2.has_key('server')
False
>>> dict2.has_key('name')
True
一个字典中混用数字和字符串的例子:
>>> dict3 = {}
>>> dict3[1] = 'abc'
>>> dict3['1'] = 3.14159
>>> dict3[3.2] = 'xyz'
>>> dict3
{'1': 3.14159, 1: 'abc', 3.2: 'xyz'}
整体赋值:
>>> dict3 = {'1': 3.14159, 1: 'abc', 3.2: 'xyz',33:'hehe'}
>>> dict3
{'1': 3.14159, 1: 'abc', 3.2: 'xyz', 33: 'hehe'}
更新字典:
>>> 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
删除字典元素和字典
>>> dict2
{'arch': 'sunos5', 'name': 'venus', 'port': 6969}
>>> del dict2['name']
>>> dict2
{'arch': 'sunos5', 'port': 6969}
>>> dict2.clear()
>>> dict2
{}
>>> del dict2
>>> dict2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'dict2' is not defined
>>> dict3
{'1': 3.14159, 1: 'abc', 3.2: 'xyz', 33: 'hehe'}
>>> dict3.pop(33)
'hehe'
>>> dict3
{'1': 3.14159, 1: 'abc', 3.2: 'xyz'}
注:避免使用内建对象名字作为变量的标识符
类似: dict,list,file,bool,str,input,len
7.2 映射类型操作符
7.2.1 标准类型操作符
>>> dict4 = {'abc': 123}
>>> dict5 = {'abc': 456}
>>> dict6 = {'abc':123,98.6:37}
>>> dict7 = {'xyz':123}
>>> dict4 < dict5
True
>>> (dict4 < dict6) and (dict4 < dict7)
True
>>> (dict4 < dict6) and (dict5 < dict7)
True
>>> dict6 < dict7
False
7.2.2 映射类型操作符
字典的键超找操作符 ([])
>>> 'name' in dict2
True
>>> 'phone' in dict2
False
7.3 映射类型的内建函数和工厂函数
7.3.1 标准类型函数[type(),str()和cmp()]
字典比较算法
>>> dict1 = {}
>>> dict2 = {'host':'earth','port':80}
>>> cmp(dict1,dict2)
-1
>>> dict1['host'] = 'earth'
>>> cmp(dict1,dict2)
-1
>>> dict1['port'] = 80
>>> cmp(dict1,dict2)
0
>>> dict1['port'] = 'tcp'
>>> cmp(dict1,dict2)
1
>>> dict2['port'] = 'udp'
>>> cmp(dict1,dict2)
-1
>>> cdict = {'fruits':1}
>>> ddict = {'fruits':1}
>>> cmp(cdict,ddict)
0
>>> cdict['oranges'] = 0
>>> cdict['apples'] = 0
>>> cmp(cdict,ddict)
1
7.3.2 映射类型相关的函数
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(x=1,y=2)
{'y': 2, 'x': 1}
>>> dict8 = dict(x=1,y=2)
>>> dict8
{'y': 2, 'x': 1}
>>> dict9 = dict(**dict8)
>>> dict9
{'y': 2, 'x': 1}
>>> dict9 = dict8.copy()
>>> dict9
{'y': 2, 'x': 1}
len()
>>> dict2 = {'name':'earth','port':80}
>>> dict2
{'name': 'earth', 'port': 80}
>>> len(dict2)
2
7.4 映射类型内建方法
>>> 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
字典类型方法
方法名称操作
dict.clear()删除字典里所有元素
dict.copy()返回字典(浅复制)的一个副本
dict.fromkeys(seq,va1=None)创建并返回一个新字典,以seq中的元素做该字典的键,val做该字典中所有键对应的初始值(如果不提供此值,默认为None)
dict.get(key,default=None)对字典dict中的键key,返回它对应的值value,如果字典中不存在此键,则返回 default的值(参数default的默认值为None)
dict.has_key
dict.items()返回一个包含字典中(键,值)对元组的列表
dict,keys()返回一个包含字典中键的列表
dict.iter()
dict.pop(key[,default])如果字典中key键存在,删除并返回dict[key],不存在,且灭有给出没认值,会引发KeyError异常
dict.setdefault(key,default=None) 如果字典不存在key键,由dict[key]=default为它赋值
dict.update(dict2)将字典dict2键值对添加到字典dict
dict.values()返回一个包含字典中所有值的列表
例:
--------------------------------
for eachKey in sorted(dict2):
... print 'dict2 key',eachKey,'has value,dict2[eachKey]'
dict2 key name has value
dict2 key port has value
---------------------------------
update()
----------------------
>>> dict2 = {'host':'earth','port':80}
>>> dict3 = {'host':'venus','server':'http'}
>>> dict2
{'host': 'earth', 'port': 80}
>>> dict2.update(dict3)
>>> dict2
{'host': 'venus', 'port': 80, 'server': 'http'}
>>> dict3.clear()
>>> dict3
{}
-----------------------
copy()
-----------------------
>>> 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()
-------------------------------------
>>> myDict = {'host':'earth','port':80}
>>> myDict.keys()
['host', 'port']
>>> myDict.items()
[('host', 'earth'), ('port', 80)]
>>> myDict.setdefault('port',8080)
80
>>> myDict.setdefault('prot','tcp')
'tcp'
>>> myDict.items()
[('host', 'earth'), ('prot', 'tcp'), ('port', 80)]
-------------------------------------
fromkeys()
--------------------------------------
>>> {}.fromkeys('xyz')
{'y': None, 'x': None, 'z': None}
>>> {}.fromkeys(('love','hour'),True)
{'love': True, 'hour': True}
--------------------------------------
7.5 字典的键
7.5.1 不允许一个键对应多个值
>>> dict1 = {'foo':789,'foo':'xyz'}
>>> dict1
{'foo': 'xyz'}
>>> dict1['foo'] = 123
>>> dict1
{'foo': 123}
7.5.2键必须是可哈希的
# vi userpw.py
-----------------------------
#!/usr/bin/env python
db = {}
def newuser():
prompt= 'please regist your name: '
while True:
name = raw_input(prompt)
if db.has_key(name):
prompt = 'name taken,try another: '
continue
else:
break
pwd = raw_input('passswd: ')
db[name] = pwd
print 'Newuser [%s] has added successfully!' %name
def olduser():
name = raw_input('login: ')
pwd = raw_input('passwd: ')
passwd = db.get(name)
if passwd == pwd:
print 'welcome back',name
else:
print 'login incorrect!'
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(Q)uit
Enter choice: """
while True:
try:
choice = raw_input(prompt).strip()[0].lower()
print 'nYou picked: [%s]' % choice
if choice not in 'neq':
print 'invalid option,please try again'
if choice == 'n':
newuser()
if choice == 'e':
olduser()
if choice == 'q':
break
except(EOFError,KeyboardInterrupt):
print 'invalid option,please try again'
if __name__ == '__main__':
showmenu()
-----------------------------
7.6 集合类型
如何创建集合类型和给集合赋值:
集合与列表和字典不同,没有特别语法格式
用集合的工厂方法可变集合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
如何访问集合中的值:
>>> '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
如何更新集合:
>>> 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'
删除集合中的成员和集合
>>> del s
>>> s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 's' is not defined
7.7 集合类型操作符
7.7.1 标准类型操作符(所有的集合类型)
成员关系(in,not in)
>>> s = set('cheeseshop')
>>> t = frozenset('bookshop')
>>> 'k' in s
False
>>> 'k' in t
True
>>> 'c' not in t
True
集合等价/不等价
>>> s == t
False
>>> s != t
True
>>> u = frozenset(s)
>>> s == u
True
>>> set('posh') == set('shop')
True
子集/超集
>>> set('shop') < set('cheeseshop')
True
>>> set('bookshop') >= set('shop')
True
7.7.2 集合类型操作符(所有的集合类型)
联合(|)
等价于or或union()方法
>>> s | t
set(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])
交集(&)
等价于and或intersection()方法
>>> s & t
set(['h', 's', 'o', 'p'])
差补
指一个集合,只属于集合s,而不属于集合t
>>> s - t
set(['c', 'e'])
对称差分(^)
指一个集合,只属于集合s或集合t,但不能同时属于两个集合
>>> s ^ t
set(['b', 'e', 'k', 'c'])
7.7.3 集合类型操作符(仅适用于可变集合)
|= 等价于update()
>>> s = set('cheeseshop')
>>> u = frozenset(s)
>>> s |= set('pypi')
>>> s
set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
7.8 内建函数:
7.8.1 标准类型函数:
len()
把集合作为参数传递给内建函数len(),返回集合的基数(或元素的个数)
>>> s = set(u)
>>> s
set(['p', 'c', 'e', 'h', 's', 'o'])
>>> len(s)
6
7.8.2集合类型工厂函数
set() and 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('%dn' %i)
...
>>> f.close()
>>> f = open('numbers','r')
>>> set(f)
set(['0n', '3n', '1n', '4n', '2n'])
>>> f.close()
7.9.1 方法
7.9.2 方法(仅适用于可变集合)
7.9.3 操作符和内建方法比较
方法名操作
s.update(t)用t中的元素修改s,即s包含s或t的成员
....
s.add(obj)在集合s中添加对象obj
s.remove(obj)从集合s中删除对象obj,如果obj不是集合s中的元素,将引发keyError错误
s.discard(obj)如果obj是集合s中的元素,从集合s中删除对象obj
s.pop()删除集合s中任意一个对象,并返回它
s.clear()删除集合s中的所有元素
7.10 操作符,函数/方法
7.11 相关模块
.....