集合是一个由唯一元素组成的非排序集合体。“非排序”是指元素不以任何特定顺序存储。用于存储集合的数据结构是散列表(hash_table),这也很好的印证里集合的定于。下面来学set有哪些操作方法。
创建集合
#创建两个空集合 set_a = set() set_b = set()
add 往集合里添加一个元素
for i in xrange(10): set_a.add(i) print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for i in xrange(5, 16): set_b.add(i) print list(set_b) #[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
#注意下面所有的操作 只和初始的这两个集合有
difference 集合独有的元素,即这些元素不在另外集合里 支持运算符 - 如set_a - set_b
set_c = set_a.difference(set_b) print list(set_c) #[0, 1, 2, 3, 4] set_c = set_a - set_b print list(set_c) #[0, 1, 2, 3, 4]
intersection 交集 支持运算符& 如set_a & set_b
set_c = set_a.intersection(set_b) print list(set_c) #[8, 9, 5, 6, 7] set_c = set_a & set_b print list(set_c) #[8, 9, 5, 6, 7]
issubset 判断集合是否是另外一个集合的子集 支持运算符 <= 如 set_a<=set_b
ret = set_a.issubset(set_b) print ret #False ret = set_a <= set_b # ret = set_a < set_b 这是严格子集即要求set_a != set_b print ret #False
issuperset 判断集合是否包含另外一个集合 支持运算符>= 如set_a>=set_b
ret = set_a.issuperset(set_b) print ret #False ret = set_a >= set_b #非严格超集 print ret #False
remove 和 discard 都是 删除某一个元素 ,区别在于remove删除的元素要在集合里,否则会引发异常;
而discard则无关紧要,即使要删除的元素不在集合里也不会引发异常
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_a.remove(1) #删除的元素需在集合里,否则会引发KeyError print list(set_a) #[0, 2, 3, 4, 5, 6, 7, 8, 9] print list(set_b) #[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] set_b.remove(5) print list(set_b) #[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
pop 也是删除元素,删除集合中第一个元素
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_a.pop() print list(set_a) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
symmetric_defference 两个集合各自中独有的元素 支持运算符 ^ 如set_a ^ set_b
set_c = set_a.symmetric_difference(set_b) print list(set_c) #[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15] set_c = set_a ^ set_b print list(set_c) #[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15]
union 合并两个集合 支持运算符 | 如set_a | set_b
set_c = set_a.union(set_b) print list(set_c) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] set_c = set_a | set_b print list(set_c) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
copy 复制一个集合
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_c = set_a.copy() print list(c) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
update 用一个集合去更新另外一个集合,无返回对象
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_c = set_a.update(set_b) print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] print set_c #None
difference_update 用差集更新一个集合,无返回对象
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_c = set_a.difference_update(set_b) #等价于set_a -= set_b print list(set_a) #[0, 1, 2, 3, 4] print set_c #None
intersection_update 用交集更新一个集合,没有返回对象
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_c = set_a.intersection_update(set_b) # 等价于 set_a &= set_b print list(set_a) #[8, 9, 5, 6, 7] print set_c #None
symmetric_difference_update 用对称差更新一个集合,没有返回对象
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_c = set_a.symmetric_difference_update(set_b) print list(set_a) #[0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15] print set_c #None
clear 清空集合
print list(set_a) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] set_a.clear() print list(set_a) #[]
字典
熟悉c++ STL的程序员对map或许很清楚吧,字典的行为类似map
字典由键/值组成的非排序可变集合体;字典扮演着一个一对一,或者多对一的角色
下面是关于字典的用法。
创建字典
dict_a = dict() #创建一个空的字典 dict_b = {} # 创建一个空的字典 dict_c = {'a':1, 'b':2, 3:'3'} # dict_d = dict( (['a', 1], ['b', '2']) ) #注意dict里面只能有一个对象 print dict_a #{} print dict_b #{} print dict_c #{'a':1, 'b':2, 3:'3'} print dict_d #{'a': 1, 'b': '2'}
往字典里添加元素,如果要添加的元素的键是已经存在的,则会覆盖掉原来的记录,故可以更新元素
dict_a = {} dict_a['a'] = 1 dict_a['b'] = 2 print dict_a #{'a': 1, 'b': 2}
删除元素,如果删除的元素不在字典中,会引发KeyError
print dict_a #{'a': 1, 'b': 2} del dict_a['b'] #如果‘b’不是字典的键则会引发KeyError print dict_a #{'a': 1}
循环访问字典
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} #方法一 for key in dict_a: print key, dict_a[key] ''' a 1 c 3 b 2 d 4 ''' for key in dict_a.keys():#方法二 print key, dict_a[key] ''' a 1 c 3 b 2 d 4 '''
字典方法:
get(kay, default=None) 返回指定键的值。如果指定键不存在则返回None
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} print dict_a.get('n') #None print dict_a.get('n', 'default') #default print dict_a.get('a') #1
items() 返回(key,value)列表
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} print dict_a.items() #[('a', 1), ('c', 3), ('b', 2), ('d', 4)]
items经常用于同时对字典中的键和值进行迭代。 但是对于大字典来说,其效率很低。这是因为items需构建一个由(key,value)组成的列表。下面这个方法有效的解决了这个问题, 利用的是迭代器
iteritems()
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} for (key, value) in dict_a.iteritems(): print key, value #maybe do other things ''' a 1 c 3 b 2 d 4 '''
values() 返回字典的所有值,在大字典中为了节省内存和提高时间效率用itervalues()迭代。values()和itervalues()
区别在于values要构建一个value的列表。
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} print dict_a.values() #[1, 3, 2, 4]
keys() 返回字典的所有键,也有迭代方法iterkeys()
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} print dict_a.keys() #字典为空则返回空列表 #['a', 'c', 'b', 'd']
update( dict object ) 用一个字典的内容对当前字典进行更新,无返回对象
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} dict_b = {'e':5, 6:7} print dict_a.update(dict_b) #None print dict_a #{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 6: 7}
has_key(key) 判断一个键是否在字典里,返回bool对象。当然这种方法已经被更好的方法取代了,用in操作符效率更好。
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} print dict_a.has_key('a') #True print dict_a.has_key('e') #False print 'a' in dict_a #True print 'e' in dict_a #False
clear 用于清空字典,删除字典用del
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} dict_a.clear() print dict_a #{}
pop(key) 删除键值为key的元素,如果key不存在则会引发KeyError
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} dict_a.pop('a') print dict_a #{'c': 3, 'b': 2, 'd': 4} dict_a.pop('e') Traceback (most recent call last): File "/home/ButterFly/codeforce.py", line 4, in <module> dict_a.pop('e') KeyError: 'e'
popitem() 删除item
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} dict_a.popitem() print dict_a #{'b':2, 'c':3, 'd':4}
copy() 复制一个字典
dict_a = {'a':1, 'b':2, 'c':3, 'd':4} dict_b = dict_a.copy() print dict_b #{'a':1, 'b':2, 'c':3, 'd':4} print id(dict_a) == id(dict_b) #False #dict_a 和dict_b 的身份是不同的
以上这些是常用的方法。通过help(dict)可知dict还有几个方法没有说到的。比如
viewitems(...)
D.viewitems() -> a set-like object providing a view on D's items
viewkeys(...)
D.viewkeys() -> a set-like object providing a view on D's keys
viewvalues(...)
D.viewvalues() -> an object providing a view on D's values
要知道这几个方法具体怎么用,可以通过__doc__ 察看