[PYTHON] 核心编程笔记之七-Python映射和集合类型

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('%d\n' %i)

...

>>> f.close()

>>> f = open('numbers','r')

>>> set(f)

set(['0\n', '3\n', '1\n', '4\n', '2\n'])

>>> 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 相关模块


.....





你可能感兴趣的:(python,映射和集合类型)