Python回顾与整理5:映像和集合类型

0.说明

        依然是按照前面介绍的几种序列类型的思路来总结字映像类型和集合类型,即先做一个介绍,再讨论可用操作符、工厂函数、内建函数和方法。


1.映射类型:字典

        映射类型被称做哈希表,而Python中的字典对象就是哈希类型,即它是按照这样的方式来存储数据:(哈希表的算法)是获取键,对键执行一个叫做哈希函数的操作,并根据计算的结果,选择在数据结构的某个地址中来存储对象的值。任何一个值存储的地址取决于它的键,正因为这种随意性,哈希表中的值是没有顺序的,所以Python中的字典对象中的元素也是无序的。

        下面是字典的基本操作:

(1)创建字典和给字典赋值

        主要的方法如下:

  • 直接创建赋值:可整体赋值,也可以逐一添加键值对
  • 工厂函数dict()

1

2

3

>>> fdict = dict((['xpleaf''boy'], ['cl''girl']))

>>> fdict

{'xpleaf''boy''cl''girl'}

  • 内建函数fromkeys():创建默认字典,字典中元素具有相同的值(如果没有给出,默认为None)

1

2

3

4

5

6

>>> fdict = {}.fromkeys(('xpleaf''cl'), 'lovings')

>>> fdict

{'xpleaf''lovings''cl''lovings'}

>>> edict = {}.fromkeys(('xpleaf''cl'))

>>> edict

{'xpleaf'None'cl'None}

(2)访问字典中的值

  • 循环字典的键

1

2

3

4

5

6

>>> fdict = {'xpleaf''boy''cl''girl'}

>>> for key in fdict.keys():

...   print key, fdict[key]

... 

xpleaf boy

cl girl

  • 使用迭代器访问类序列对象

1

2

3

4

5

6

>>> fdict = {'xpleaf''boy''cl''girl'}

>>> for key in fdict:

...   print key, fdict[key]

... 

xpleaf boy

cl girl

  • 先判断键值是否存在再访问

1

2

3

4

5

6

7

>>> fdict = {'xpleaf''boy''cl''girl'}

>>> fdict.has_key('xpleaf')

True

>>> 'xpleaf' in fdict

True

>>> 'clyyh' in fdict

False

(3)更新字典

        可以更新已有的键值对或添加新的键值对:


1

2

3

4

5

>>> fdict = {'host''xpleaf''port'80}

>>> fdict['port'= 3389

>>> fdict['ip'= '121.42.147.131'

>>> print 'host: %(host)s, port: %(port)s, ip: %(ip)s' % fdict

host: xpleaf, port: 3389, ip: 121.42.147.131

(4)删除字典元素和字典


1

2

3

4

>>> fdict = {'host''xpleaf''port'80'ip''121.42.147.131'}

>>> del fdict['port']  #删除一个键值对

>>> fdict.clear()        #删除字典中所有的键值对

>>> del fdict             #删除整个字典


2.映射类型操作符

        除了不支持拼接和重复,字典可以和所有的标准类型操作符一起工作。

(1)标准类型操作符

        在《Python回顾与整理2:Python对象》中已经有介绍过标准类型操作符,它们对字典类型也是适合的,主要是:>、<、==和and等,如下:


1

2

3

4

5

6

>>> dict1 = {'abc'123}

>>> dict2 = {'abc'456}

>>> dict1 < dict2

True

>>> dict1 == dict2

False

(2)映射类型操作符

  • 字典的键查找操作符([])

        对序列类型来说,用索引做唯一参数或下标以获取一个序列的值,但是对字典来说,是用键查询,键是参数,而不是索引。通过`[]`操作符,可以在字典中查找元素,也可以为某个元素赋值。

  • 键成员关系操作(in、not in)

        当然也可以用has_key()。


3.映射类型的内建函数和工厂函数

(1)标准类型函数type()、str()、cmp()

        这里不介绍cmp(),因为字典的比较算法比较复杂,而且不是很经常用,其它两个如下:


1

2

3

4

5

6

7

>>> d = {'name''xpleaf''age'21}

>>> str(d)

"{'age': 21, 'name': 'xpleaf'}"

>>> unicode(d)

u"{'age': 21, 'name': 'xpleaf'}"

>>> type(d)

<type 'dict'>

(2)映射类型相关的函数

  • dict()

        如果参数是容器类型并且是可迭代的,那么可抚今追昔的元素必须成对出现,从而生成一个字典:


1

2

3

4

5

6

7

8

>>> dict(zip(('x''y'), (12)))

{'y'2'x'1}

>>> dict([['x'1], ['y'2]])

{'y'2'x'1}

>>> [('xy'[i-1], i) for in range(13)]

[('x'1), ('y'2)]

>>> dict([('xy'[i-1], i) for in range(13)])

{'y'2'x'1}

        如果参数也是一个映射类型,比如一个字典对象,则会生成一个浅拷贝,但建议使用copy()方法:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

>>> d = {'name''xpleaf''age'21}

>>> d2 = dict(d)

>>> d2

{'age'21'name''xpleaf'}

>>> id(d), id(d2)

(139762050623200139762085625480)

>>> [(id(x), id(d[x])) for in d]

[(13976208561863223490424), (139762086747760139762085603104)]

>>> [(id(x), id(d[x])) for in d2]

[(13976208561863223490424), (139762086747760139762085603104)]

>>> 

>>> d3 = d2.copy()

>>> d3

{'age'21'name''xpleaf'}

        当然dict()还可以接受关键字参数:


1

2

>>> dict(x=1, y=2)

{'y'2'x'1}

  • len():返回字典键值对的个数

1

2

3

>>> d = {'name''xpleaf''age'21}

>>> len(d)

2

  • hash():不是为字典设计的方法,但是可以判断某个对象是否可以作为一个字典的键

1

2

3

4

5

6

>>> hash('xpleaf')

-166083108737309362

>>> hash([])

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: unhashable type'list'

        另外,即使那个对象的数据类型不同,但只要它们的值相同,所得哈希值也是一样的:


1

2

3

4

>>> hash('xpleaf')

-166083108737309362

>>> hash(u'xpleaf')

-166083108737309362


4.映射类型内建方法

        常见的内建方法如下:

  • dict.clear():删除字典中的所有元素

1

2

3

4

5

6

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d

{'age'21'name''xpleaf''loving''cl'}

>>> d.clear()

>>> d

{}

  • dict.copy():返回字典的一个浅拷贝
  • dict.fromkeys(seq, val=None):创建并返回一个字典,以seq中的元素做该字典的键,val做该字典中所有键对的初始值(如果不提供些值,则默认为None)

1

2

3

4

>>> {}.fromkeys(('name''age''loving'), 'Not set')

{'age''Not set''name''Not set''loving''Not set'}

>>> {}.fromkeys(('name''age''loving'))

{'age'None'name'None'loving'None}

  • dict.get(key, default=None):返回字典中key对应的value,如果字典中不存在此键,则返回default的值(参数default的默认值为None)

1

2

3

4

5

6

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.get('name')

'xpleaf'

>>> d.get('clyyh')

>>> d.get('clyyh''Not found')

'Not found'

  • dict.has_keys():判断键是否存在于字典中,但现在建议用成员操作符in和not in
  • dict.items():返回一个包含字典中、键值对元组的列表

1

2

3

4

5

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.items()

[('age'21), ('name''xpleaf'), ('loving''cl')]

>>> sorted(d.items())    #排序输出

[('age'21), ('loving''cl'), ('name''xpleaf')]

  • dict.keys():返回一个包含字典中键的列表

1

2

3

4

5

6

7

8

9

10

11

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.keys()

['age''name''loving']

>>> sorted(d.keys())    #排序输出

['age''loving''name']

>>> sort_keys = d.keys()

>>> sort_keys

['age''name''loving']

>>> sort_keys.sort()    #调用列表的sort()方法

>>> sort_keys

['age''loving''name']

  • dict.values():返回一个包含字典中所有值的列表

1

2

3

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.values()

[21'xpleaf''cl']

  • dict.iter*():方法iteritems()、iterkeys()、itervalues()与它们对应的非迭代方法一样,不同的是它们返回一个迭代子,而不是一个列表

1

2

3

4

5

6

7

8

9

10

11

12

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> iter_keys = d.iterkeys()

>>> iter_keys

<dictionary-keyiterator object at 0x7f1ce39a25d0>

>>> type(iter_keys)

<type 'dictionary-keyiterator'>

>>> for key in iter_keys:

...   print key

... 

age

name

loving

        当字典非常大时,使用这三种方法就可以大大节省内存空间,因为这三种方法的非迭代子方法返回的数据是直接存储在内存当中的,而这三种方法返回的是一个迭代子,可以理解为一个函数,用于动态获取字典中的这些值。

  • dict.pop(key[, default]):和get()方法类似,如果字典中key键存在,删除并返回dict[key];如果key键不存在,且没有给出default的值,则引发KeyError异常(这点与get()方法不同)

1

2

3

4

5

6

7

8

9

10

11

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.pop('loving')

'cl'

>>> d

{'age'21'name''xpleaf'}

>>> d.pop('clyyh''Not found')

'Not found'

>>> d.pop('clyyh')

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

KeyError: 'clyyh'

  • dict.popitem():随机删除一对键值对并以元组的形式返回

1

2

3

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.popitem()

('age'21)

  • dict.setdefault(key, default=None):检查字典中是否含有某键,如果这个键存在,则返回该键对应的值;如果不存在,则可以给这个键赋默认值并返回此值

1

2

3

4

5

6

7

8

9

10

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d.setdefault('name')

'xpleaf'

>>> d.setdefault('clyyh')

>>> d

{'age'21'clyyh'None'name''xpleaf''loving''cl'}

>>> d.setdefault('love''Not set')

'Not set'

>>> d

{'love''Not set''age'21'clyyh'None'name''xpleaf''loving''cl'}

  • dict.update(dict2):将字典dict2的键值对添加到dict中,字典中原有的键如果与新添加的键重复,那么原来字典中该键所对应的值就会被更新覆盖

1

2

3

4

5

>>> d = {'name''xpleaf''age'21'loving''cl'}

>>> d2 = {'name''yonghaoye''clyyh''forever'}

>>> d.update(d2)

>>> d

{'age'21'clyyh''forever''name''yonghaoye''loving''cl'}


5.字典的键

        字典中的值是没有任何限制的,可以是任意Python对象,但是字典中的键是有限制的。

(1)不允许一个键对应多个值

        从字典的存储方式去理解,这也是很合理的,因为值的存储地址就是通过字典的键来生成的。当有键发生冲突(即字典键重复赋值)时,会取最后(最近)的赋值,而不会产生错误,这是因为如果对每一个键值对赋值时都检查该键是否存在,会占用一定的内存,相比之下,直接把该键原来对应的值覆盖的性能会更好。


1

2

3

4

5

6

>>> d = {'name''xpleaf''name''clyyh'}

>>> d

{'name''clyyh'}

>>> d['name'= 'xpleaf'

>>> d

{'name''xpleaf'}

(2)键必须是可哈希的

  • 对于不可变对象,值相等,表示的键相同

1

2

3

>>> d = {u'name''xpleaf''name''xpleaf'1'clyyh'1.0'clyyh'}

>>> d

{1'clyyh', u'name''xpleaf'}

  • 有一些可变对象是可哈希的,如定义了__hash__()特殊方法的类

        因为__hash__()方法返回一个整型,所以仍然是用不可变的值来做字典的键。

  • 为什么键是可哈希的

        解释器调用哈希函数,根据字典中的值来计算存储数据的位置。如果键是可变对象,那么它的值可改变。当键发生变化时,哈希函数会映像到不同的地址来存储数据。如果这样的情况发生,哈希函数就不可能可靠地存储或获取相关的数据。选择可哈希的键的原因就是因为它们的值不能改变。


6.集合类型

        在数学上,集合由不同的元素组成,Python把这个概念引入到集合类型对象中。

        在Python集合中,集合对象的成员(集合元素)是一组无序排列的可哈希的值,这也意味着集合的元素是不可变对象,因此都可以作为字典的键。而Python中的集合又可以分为两种:

  • 可变集合set:可以添加和删除元素,是一个不可哈希的集合对象,因此不可以作为字典中的键或其他集合中的元素

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

>>> set_a = set('xpleaf')

>>> set_a

set(['a''e''f''l''p''x'])        #无序排列

>>> hash(set_a)        #不可哈希

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: unhashable type'set'

>>> set_a.add('clyyh')    #添加元素

>>> set_a

set(['a''e''f''l''p''x''clyyh'])

>>> set_a.remove('clyyh')        #删除元素

>>> set_a

set(['a''e''f''l''p''x'])

>>> set_a.add(set('clyyh'))  #set集合本身不可以作为集合中的元素,因为集合中的元素必须是可哈希的

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: unhashable type'set'

  • 不可变集合frozenset:不可以添加和删除元素,是一个可哈希的集合对象,因此可以作为字典中的键或是作为集合中的一个成员

1

2

3

4

5

6

7

8

9

10

>>> frozenset_b = frozenset('xpleaf')

>>> frozenset_b

frozenset(['a''e''f''l''p''x'])

>>> hash(frozenset_b)

6226730480975949720

>>> dir(frozenset_b)        #没有添加和删除元素的方法

['__and__''__class__''__cmp__''__contains__''__delattr__''__doc__''__eq__''__format__''__ge__''__getattribute__''__gt__''__hash__''__init__''__iter__''__le__''__len__''__lt__''__ne__''__new__''__or__''__rand__''__reduce__''__reduce_ex__''__repr__''__ror__''__rsub__''__rxor__''__setattr__''__sizeof__''__str__''__sub__''__subclasshook__''__xor__''copy''difference''intersection''isdisjoint''issubset''issuperset''symmetric_difference''union']

>>> set_a.add(frozenset_b)    #frozenset集合可以作为集合中的元素

>>> set_a

set(['a''e''f''l''p'frozenset(['a''e''f''l''p''x']), 'x'])

        但需要注意的是,因为集合本身是无序的,不可以为集合创建索引或执行切片操作,也没有键可用来获取集合中的元素:


1

2

3

4

5

6

7

8

9

10

11

>>> set_a = set('xpleaf')

>>> set_a

set(['a''e''f''l''p''x'])

>>> set_a[0]

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: 'set' object does not support indexing

>>> set_a['a']

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: 'set' object has no attribute '__getitem__'

        下面是数学集合操作符与Python集合操作符的对比说明:

集合操作符和关系符号
数学符号 Python符号 说明
in 是……的成员
not in 不是……的成员
= == 等于
!= 不等于
< 是……的真子集
<= 是……的子集
> 是……的真超集
>= 是……的超集
& 交集
| 并集
-或\ - 差集或相对补集
Δ ^ 对称差分

        下面是集合的基本操作:

  • 创建集合类型和给集合赋值

        与列表和字典不同,集合只能通过工厂函数set()或frozenset()来创建:


1

2

3

4

5

6

>>> a = set('xpleaf')

>>> b = frozenset('xpleaf')

>>> type(a)

<type 'set'>

>>> type(b)

<type 'frozenset'>

  • 访问集合中的值

        可以通过遍历或检查某项元素中否是一个集合的成员来实现:


1

2

3

4

5

6

7

>>> s = set('xpleaf')

>>> 'x' in s

True

>>> for in s:

...   print i,

... 

a e f l p x

  • 更新集合

        对于可变集合set,可以使用集合的内建方法add()、remove()、update()和操作符`-`等来更新集合:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

>>> s = set('xpleaf')

>>> s

set(['a''e''f''l''p''x'])

>>> s.add('clyyh')

>>> s

set(['a''e''f''l''p''x''clyyh'])

>>> 

>>> s.remove('clyyh')

>>> s

set(['a''e''f''l''p''x'])

>>> 

>>> s.update('cl')        #注意update()是先将'cl'变为一个集合再合并到原来集合中,这与add()方法不同

>>> s

set(['a''c''e''f''l''p''x'])

>>> 

>>> s -= set('xpleaf')

>>> s

set(['c'])

  • 删除集合中的成员和集合本身

        删除集合中的成员只针对于可变集合,上面已有提及,而对于集合本身,可以直接使用del来删除。


7.集合类型操作符

(1)标准类型操作符(适用于所有集合类型)

  • 成员关系(in、not in)

1

2

3

4

5

>>> s = set('xpleaf')

>>> 'x' in s

True

>>> 'c' in s

False

  • 集合等价/不等价(==、!=)

        可以认为是数学中的集合相等与不相等,两种集合之间也可以比较:


1

2

3

4

5

6

>>> set('xpleaf'== frozenset('xpleaf')

True

>>> set('xpleaf'== frozenset('leaf')

False

>>> set('xpleaf') != frozenset('leaf')

True

  • 子集/超集(<、<=、>、>=)

        直接从元素是否相互包含的角度去理解即可:


1

2

3

4

5

6

>>> set('xpleaf') > frozenset('leaf')

True

>>> set('xpleaf') > frozenset('xpleaf')

False

>>> set('xpleaf') >= frozenset('xpleaf')

True

(2)集合类型操作符(适用于所有的集合类型)

  • 并集(|)

1

2

3

4

>>> s = set('xpleaf')

>>> t = frozenset('leafhao')

>>> s | t

set(['a''e''f''h''l''o''p''x'])

        当然也可以使用集合的内建方法union():


1

2

3

4

>>> s.union(t)

set(['a''e''f''h''l''o''p''x'])

>>> t.union(s)

frozenset(['a''e''f''h''l''o''p''x'])

  • 交集(&)      

1

2

3

4

>>> s = set('xpleaf')

>>> t = frozenset('leafhao')

>>> s & t

set(['a''e''l''f'])

        除了使用`&`操作符,也可以使用集合的内建方法intersection():


1

2

>>> s.intersection(t)

set(['a''e''l''f'])

  • 差集/相对补集(-)

1

2

3

4

5

6

>>> s = set('xpleaf')

>>> t = frozenset('leafhao')

>>> s - t

set(['p''x'])

>>> t - s

frozenset(['h''o'])

        除了使用`-`操作符,也可以使用集合的内建方法difference():


1

2

3

4

>>> s.difference(t)

set(['p''x'])

>>> t.difference(s)

frozenset(['h''o'])

  • 对称差分(^)

        两个集合(s和t)的对称差分是指另外一个集合C,该集合中的元素只能是属于集合s或者集合t的成员,不能同时属于两个集合(类似于异或):


1

2

3

4

>>> s = set('xpleaf')

>>> t = frozenset('leafhao')

>>> s ^ t

set(['p''x''h''o'])

        除了使用`-`操作符,也可以使用集合的内建方法symmetric_dirrerence():


1

2

>>> s.symmetric_difference(t)

set(['p''x''h''o'])

  • 混合集合类型操作符

        在上面的演示中,左边的s是可变集合,而右边的t是一个不可变集合,而所得的结果是可变集合,但如果把两个操作数的顺序反过来,结果就不一样了:


1

2

3

4

5

6

>>> t | s

frozenset(['a''e''f''h''l''o''p''x'])

>>> t ^ s

frozenset(['p''h''x''o'])

>>> t - s

frozenset(['h''o'])

        即如果左右两个操作数的类型相同,则所产生的结果类型是相同的;如果不相同,则结果与左操作数的类型相同。但需要注意的是,加号`+`并不是集合类型的操作符:


1

2

3

4

>>> s + set('leaf')

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: unsupported operand type(s) for +'set' and 'set'

(3)集合类型操作符(仅适用于可变集合)

        其实就上面的四种操作符,只不过将其作为方法加进可变集合中或通过操作符实现,从而直接对可变集合本身产生影响:

  • 并集更新(|=或update())

1

2

3

4

5

6

7

>>> s = set('xpleaf')

>>> s2 = set('leafhao')

>>> s

set(['a''e''f''l''p''x'])

>>> s |= s2

>>> s

set(['a''e''f''h''l''o''p''x'])

  • 保留更新(&=或intersection_update())

1

2

3

4

5

6

7

>>> s = set('xpleaf')

>>> s2 = set('leafhao')

>>> s

set(['a''e''f''l''p''x'])

>>> s &= s2

>>> s

set(['a''e''l''f'])

  • 差集更新(-=或difference_update())

1

2

3

4

5

6

7

>>> s = set('xpleaf')

>>> s2 = set('leafhao')

>>> s

set(['a''e''f''l''p''x'])

>>> s -= s2

>>> s

set(['p''x'])

  • 对称差分更新(^=或symmetric_diffenence_update())

1

2

3

4

5

6

7

>>> s = set('xpleaf')

>>> s2 = set('leafhao')

>>> s

set(['a''e''f''l''p''x'])

>>> s ^= s2

>>> s

set(['h''o''p''x'])


8.内建函数

(1)标准类型函数

  • len():返回一个集合中元素的个数

1

2

3

4

5

6

>>> s = set('xpleaf')

>>> t = frozenset('clyyh')

>>> len(s)

6

>>> len(t)

4

(2)集合类型工厂函数

        主要是set()和frozenset(),分别用来生成可变和不可变集合,主要有下面两种方式:

  • 不提供参数:默认生成空集合

1

2

3

4

>>> set()

set([])

>>> frozenset()

frozenset([])

  • 提供参数:如果提供参数,则该参数必须是可迭代的,即一个序列,或迭代器,或支持迭代的一个对象,例如一个文件或一个字典

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

>>> set(['xpleaf''clyyh'])

set(['clyyh''xpleaf'])

>>> 

>>> frozenset({'name''xpleaf''age'21})

frozenset(['age''name'])

>>> 

>>> f = open('numbers''w')

>>> for 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()


9.集合类型内建方法

(1)适用于所有集合类型的方法

        如下:

方法名称 操作
s.issubset(t) 如果s是t的子集,则返回True,否则返回False
s.issuperset(t) 如果t是s的超集,则返回True,否则返回False
s.union(t) 返回一个新集合,该集合是s和t的并集
s.intersection(t) 返回一个新集合,该集合是s和t的交集
s.difference(t) 返回一个新集合,该集合是s的成员,但不是t的成员
s.symmetric_difference(t) 返回一个新集合,该集合是s或t的成员,但不是s和t共有的成员
s.copy() 返回一个新集合,它是集合s的浅复制

        需要注意的是,内建方法copy()没有等价的操作符,和同名的字典内建方法dict.copy()一样,copy()方法比用像set()、frozenset()或dict()这样的工厂方法提制对象的副本要快,测试程序如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#!/usr/bin/env python

from time import time

 

 

def get_set_time():

    start_time = time()

    = set('xpleaf')

    end_time = time()

    return end_time - start_time

 

 

def get_copy_time():

    = set('xpleaf')

    start_time = time()

    s2 = s.copy()

    end_time = time()

    return end_time - start_time

 

 

def get_result():

    s_longer_than_c = 0

    times = 100

    for in range(times):

        if get_set_time() > get_copy_time():

            s_longer_than_c += 1

    if s_longer_than_c != 0:

        return s_longer_than_c/float(times)

 

 

if __name__ == '__main__':

    rate = get_result()

    print 'Result***'

    print 'The rate that set_method_time is longer than copy_method_time is:', rate

        执行如下:


1

2

3

/usr/bin/python2.7 /home/xpleaf/PycharmProjects/Python_book/7/test_time.py

Result***

The rate that set_method_time is longer than copy_method_time is: 0.51

        当然,并不总是如此的,有时候会小于0.5,并且可能性也不小,这里只是作为简单的测试而已,实际上在使用时不用纠结太多。

(2)只适用于可变集合的方法

        如下:

方法名称 操作
s.update(t) 用t中的元素修改s,即,s现在包含s或t的成员
s.intersection_update(t) s中的成员是共同属于s和t的元素
s.difference_update(t) s中的成员是属于s但不包含在t中的元素
s.symmetric_difference_update() s中的成员更新为那些包含中s或t中,但不是s和t共有的元素
s.add(obj) 在集合s中添加对象obj
s.remove(obj) 从集合s中删除对象obj;如果obj不是集合s中的元素(obj not in s),将引发KeyError错误
s.discard() 如果obj是集合s中的元素,从集合s中删除对象obj
s.pop() 删除集合s中的任意一个对象,并返回它
s.clear() 删除集合s中的所有元素

        有了前面的基础之后,这些方法都比较简单,所以这里就不给出例子了,不过需要注意的是,需要接受参数的方法,其参数必须是可哈希的。

(3)操作符和内建方法比较

        像上面看到的那样,很多内建的方法几乎和操作符等价。之所以说几乎等价而不是完全等价,是因为:当用操作符时,操作符两边的操作数必须是集合,而在使用内建方法时,对象也可以是迭代类型的。原因:采用易懂的set('abc').intersection('cbs')可以避免使用set('abc') `操作符` 'cbs'这样容易出错的构建方法。可以看下面的一个例子:


1

2

3

4

5

6

7

8

9

>>> s = set('xpleaf')

>>> s.intersection('leaf')

set(['a''e''l''f'])

>>> s & set('leaf')

set(['a''e''l''f'])

>>> s & 'leaf'

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: unsupported operand type(s) for &: 'set' and 'str'


10.集合类型总结表

        可以参考书上的总结表,非常详细。


11.相关模块

        可以不用考虑,直接使用映射和集合类型即可。

时间: 2024-12-27 07:29:00

Python回顾与整理5:映像和集合类型的相关文章

Python回顾与整理7:文件和输入输出

0.说明                  主要是下面的内容: 文件对象:内建函数.内建方法.属性 标准文件 文件系统:访问方法.文件执行 持久化存储 标准库中与文件有关的模块 1.文件对象         文件对象是用来访问文件的接口,而文件只是连续的字节序列,数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成. 2.文件内建函数(open()和file())         内建函数open()以及file()提供了初始化输入/输出(I/O)操作的通用接口,如果打开文件成功,

Python回顾与整理4:序列1—字符串

0.说明                  序列其实是Python的某几类数据类型的统称,如字符串,列表和元组,将它们统称为序列,是因为:它们的成员有序排列,并且可以通过下标偏移量访问到它的一个或者几个成员.         总结的思路为:先介绍适用于所有序列类型的操作符和内建函数,然后再分别对这几种序列类型进行介绍. 1.序列         序列类型都有相同的访问模式:它的每一个元素都可以通过指定一个偏移量的方式得到,多个元素通过切片操作的方式得到.而在Python序列中,偏移量的规则如下(

Python回顾与整理3:数字

0.说明               数字用的次数是否多主要是看需求,如果是做自动化运维平台开发,比如做一个自动监控的系统,那么你肯定需要收集一定量的数据,然后再对这些数据做一定的处理,那么这时候,你就一定需要用得上数字的.当然,我这里所说的要不要用数字,指的是,你是否需要对你的数据做一定的处理. 1.数字简介         数字是不可更改类型,也就是说变更数字的值会生成新的对象. (1)创建数值对象并用其赋值(数字对象) 1 2 >>>anInt = 1 >>>aC

Python回顾与整理4:序列2—列表与元组

1.列表         与字符串不同的是,列表不仅可以包含Python的标准类型,还可以包含不同类型的对象,包括用户自定义的对象.下面是一些列表的最基本的操作: 创建列表数据类型:由方括号([ ])定义,当然也可以用工厂方法list(iter)创建 访问列表的值:通过切片操作符([ ])和索引值或索引值范围访问 更新列表:可以在等号左边指定一个索引或者索引范围的方式来更新一个或几个元素,也可以用append()方法追加新元素到列表中 删除列表元素或列表本身:使用del L[index]的方法,

Python回顾与整理11:面向对象编程

0.说明         阅读一些优秀的Python源代码,会发现面向对象编程的思想无处不在,其实对于任何一门面向对象编程语言来说,面向对象编程都是极其重要的,因此,掌握好一门语言的面向对象编程,将有助于进行更高级的开发.(本文来自香飘叶子51cto博客<Python回顾与整理>系列博文专题) 1.引言 (1)类与实例 类         在Python中有新式类和经典类之分,无非就是有没有显式地继承一个父类: 1 2 3 4 5 6 7 # 新式类 class MyNewObjectType

Python回顾与整理2:Python对象

0.说明                  说对象是面向对象编程语言最重要的一部分一点也不为过,没有了"对象",面向对象将无从谈起.Python也是如此,如果无法掌握对象,你很难有大的进步与提升. 1.Python对象 (1)对象特性         Python使用对象模型来存储数据,构造任何类型的值都是一个对象,所有的Python对象都拥有下面的三个特性: 身份:每个对象一唯一身份标识,可使用内建函数id()查看该值(可以认为这个值是该对象的内在地址) 类型:对象的类型决定了对象(

Python回顾与整理1:Python基础

0.说明                  学习Python其实也有好一段时间了,之前也做了不少笔记,但是要真正把Python学得很扎实,没有对Python系统的了解是远远不够的,哪怕是最基础的知识点,所以决定好好地回顾整理.         当然,就以<Python核心编程>这本书为纲,希望可以把自己对Python的理解连成系统的一条线. 1.语句和语法 `#`:注释 `\`:换行,如果是闭合操作符如`( )`,`[ ]`,`{ }`等,可以不使用`\` `:`:分号将代码头和代码体分开 `

Python回顾与整理8:错误和异常

0.说明         如果想写出用户体验高的代码,那么就需要考虑到在执行自己写的这段代码中在和用户交互的过程中可能会出现的问题,也就是说,需要对可能出现的异常进行处理,只有做好这些工作,才能写出用户体验好的代码. 1.什么是异常 错误         错误是语法(导致解释器无法解释)或逻辑(也就是代码质量问题)上的,在Python中,当检测到错误时,解释器会指出当前流无法继续执行下去,于是就出现了异常. 异常         程序出现了错误而在正常控制流以外采取的行为.         根据

Python回顾与整理9:函数和函数式编程

0.说明         无论在什么编程语言中,函数都不可或缺,充分利用函数的特性,可以大大减少我们程序中的代码量. 1.什么是函数         所谓函数,英文名为function,其实就是表示为实现一定功能的一段代码,显然,如果需要多次实现某一功能时,使用函数就是把重复代码放入其中,既节省空间,又有助于保持一致性(主要是修改代码时). (1)函数vs过程         两者都是可以被调用的实体,过程是简单.没有返回值.特殊的函数.在Python中,过程就是函数,因为解释器会隐匿地返回默认