您的位置:首页 > 编程语言 > Python开发

python 之SET和collections

2016-01-22 10:35 330 查看
一.set集合
set是一个无序且不重复的元素集合,基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)、sysmmetric difference(对称差集)等数学运算.
优点:访问速度快,原生解决了重复问题
set拥有类似dict的特点:可以用{}花括号来定义;其中的元素没有序列,也就是是非序列类型的数据;而且,set中的元素不可重复,这就类似dict的键.
set也有继承了一点list的特点:如可以原处修改
举例:
>>> s1 = set("lkajdsfd") 建立一个set
>>> s = set(['h','a','b']) 这里可以把一个列表纳入到一个集合中
>>> x, y 查看多个set
(set(['a', 'p', 's', 'm']), set(['a', 'h', 'm']))
>>> s1
set(['a', 'd', 'f', 'k', 'j', 'l', 's'])
>>> s2 = set([123,"goolge","face","book","face"])
>>> s2
set(['book', 123, 'goolge', 'face'])
>>> s1
set(['a', 'd', 'f', 'k', 'j', 'l', 's'])
>>> s3 = {"alsdjkfa","123"} 另一种建立set的方式,当仅有key时候,默认会建立一个set
>>> s3
set(['123', 'alsdjkfa'])
>>> type(s3)
<type 'set'>
>>> s4 = {} 当{} 为空时候建立为int格式
>>> type(4)
<type 'int'>
>>> s5 = { } 当{}里面有内容时候,默认建立为dict
>>> type(s5)
<type 'dict'>
set的一些内置功能:
1.set() -> new empty set object
2.set(iterable) -> new set object
3.add
在集合中添加一个元素.
举例:
>>> s1.add("dddsd")
>>> s1
set(['a', 'd', 'f', 'k', 'j', 'l', 's', 'dddsd'])
注意:s1.add([1,2,3])这样添加方法是不行的,需要s1.add("[1,2,3]") 因为set添加只认添加一个元素。只支持一次添加一个,不支持一次添加多个。
4.clear
删除集合中的所有元素(危险操作)
举例:
>>> s1
set(['a', 'd', 'f', 'k', 'j', 'l', 's', 'dddsd'])
>>> s1.clear()
>>> s1
set([])
5.copy,浅copy
举例:
>>> s6 = s1.copy()
>>> s6
set(['face', 123, 'aadf', 'book', 'goolge'])
返回s1的一个浅copy
6.pop
随机的从原有集合中获取一个元素,并把获取的这个元素,从原有集合中移除,这个元素的输出可以给一个变量。如果为空则引发 KeyError
举例:
>>> s2 = set(['test1','test2','test3','test1'])
>>> s2
set(['test1', 'test3', 'test2'])
>>> ret =s2.pop()
>>> ret
'test1'
>>> ret =s2.pop()
>>> ret
'test3'
>>> s2
set(['test2'])
>>> ret
'test3'
>>> ret =s2.pop()
>>> ret
'test2'
>>> s2
set([])
7.remove
直接从集合里面移除一个元素,若不存在报KeyError错误。
s2.remove('test1')
set(['test1', 'test3', 'test2'])
>>> s2.remove('test1')
>>> s2
set(['test3', 'test2'])
>>> s2.remove('test1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'test1'
8.discard(self, *args, **kwargs): # real signature unknown
移除元素,与remove不同的是删除无论是否在集合中都不会有返回值。
举例:
>>> s2
set(['test3', 'test2'])
>>> s2.discard('test1')
>>> s2.discard('test2')
>>> s2
set(['test3'])
9.difference
会生产一个新的集合,不改变原有的集合。取的过程中,循环原来的元素,判断原来的元素,是否在新的里面。
10.difference_update
删除当前set中的所有包含在 (new set) 参数集合 里的元素 """更新原有的集合。
11.intersection
""" 取交集,新创建一个set ""
12.intersection_update
""" 取交集,修改原来set """
13.isdisjoint
""" 如果没有交集,返回true """
14.issubset
""" 是否是子集 """
15.issuperset
""" 是否是父集 """
16.symmetric_difference(self, *args, **kwargs): # real signature unknown
""" 差集,创建新对象"""
对称差 把两个不一样的全拿出来。会生产一个新的集合
17.symmetric_difference_update(self, *args, **kwargs): # real signature unknown
""" 差集,改变原来 """ 对称差 把两个不一样的全拿出来。更新原有集合
18.union(self, *args, **kwargs): # real signature unknown
""" 并集 """ 交集
19.update(self, *args, **kwargs): # real signature unknown
""" 更新 """
20.__eq__(self, y): # real signature unknown; restored from __doc__
""" x.__eq__(y) <==> x==y """

例子1:
场景描述:现在需要把新的(new_dict)数据更新到旧的(old_dict)数据中。
#!/usr/bin/env python
# -*-coding:utf-8 -*-
old_dict = {
"#1":{'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 },
"#2":{'hostname':'c2', 'cpu_count': 2, 'mem_capicity': 80 },
"#3":{'hostname':'c3', 'cpu_count': 2, 'mem_capicity': 80 }
}

new_dict = {
"#1":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 512},
"#3":{ 'hostname':'c3', 'cpu_count': 2, 'mem_capicity': 1024},
"#4":{ 'hostname':'c4', 'cpu_count': 2, 'mem_capicity': 80}
}

import collections #导入模块
my_dict = collections.defaultdict(list) #配置默认字典
old_key = old_dict.keys()
new_key = new_dict.keys()
old = set(old_key)
new = set(new_key)
updagte_list = set(old.intersection(new))
delect_list = old.difference(updagte_list)
delect_list = old.difference(updagte_list)
add_list = new.difference(updagte_list)
updagte_add_list = updagte_list.union(add_list)
my_dict = old_dict
for i in updagte_add_list:
my_dict[i] = new_dict[i]
for it1 in delect_list:
del my_dict[it1]
print (my_dict)
例子2:关于difference和symmetric_difference的区别
s2 = set(['test1','test2','test3','test1'])
s3 = set(['test1','test2','test5'])
print(s2.difference(s3))
#difference 在s3中有的拿掉,没有的不管
print(s2.symmetric_difference(s3))
执行的结果为:
set(['test1', 'test3', 'test2'])
set(['test3'])
set(['test3', 'test5'])
--------------------------------------------------------------------------------------------------------------------
二、collections 系列是对字典类型的一个补充。
Counter 计数器
orderedDict 有序字典
defaultdict 默认字典
namedtuple 可命名元组

1.Counter计数器,目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。继承字典的一些特性和功能。当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。
注:字典的参数也可以使用。
1.1 创建一个计数器,Counter是对字典类型的补充,用于追踪值的出现次数。
举例:
import collections
test = ('asdfasdfew')
a =collections.Counter(test)
print(type(a))
print(a)
执行结果:
<class 'collections.Counter'>
Counter({'a': 2, 'd': 2, 'f': 2, 's': 2, 'w': 1, 'e': 1})
1.2 most_common(self, n=None):数量大于等n的所有元素和计数器
print(a.most_common(2))
[('a', 2), ('s', 2)] #注意获得结果是随机的。
1.3 __missing__(self, key):对于不存在的元素,返回计数器为0
print(a.__missing__('w'))
执行结果:0
1.4elements(self):计数器中的所有元素,注:此处非所有元素集合,而是包含所有元素集合的迭代器,会把计数器中的所有元素逐一罗列出来。
'''Iterator over elements repeating each as many times as its count.
举例:
import collections
test = ('asdfasdfew')
a =collections.Counter(test)
#test = collections.Counter('ADFASDFADSFEADFASDF')
for i in a.elements():
print(i)
执行结果:
C:\Python34\python.exe E:/Python/S12/day1/test1.py
d
d
f
f
a
a
w
s
s
e
1.5 update(self, iterable=None, **kwds):可以使用一个iterable对象或者另一个Counter对象来更新键值。计数器的更新包括增加和减少两种。
>>> import collections
>>> c = collections.Counter('which')
>>> c.update('witch') # 使用另一个iterable对象更新
>>> c['h']
执行结果:3
>>> d = Counter('watch')
>>> c.update(d) # 使用另一个Counter对象更新
>>> c['h']
1.6 subtract(self, iterable=None, **kwds): 相减,原来的计数器中的每一个元素的数量减去后添加的元素的数量
举例:
>>> import collections
>>> c = collections.Counter('test')
>>> c.subtract('text')
>>> c
Counter({'s': 1, 'e': 0, 't': 0, 'x': -1})
1.7 copy(self): """ 拷贝 """
1.8 __reduce__(self): """ 返回一个元组(类型,元组) """
1.9 __delitem__(self, elem): """ 删除元素 """

例子:
#items = > 处理完成的值
import collections #导入collections模块(Counter模块在collections中)
obj = collections.Counter('ASDFLKJASDLKFJAKDSJFASDJFD')
print(obj)
ret = obj.most_common(4) #拿到前四位
print(ret)
for k,v in obj.items():
print (k,v)
执行结果:
C:\Python27\python.exe E:/Python/S12/day3/s1.py
Counter({'D': 5, 'A': 4, 'F': 4, 'J': 4, 'S': 4, 'K': 3, 'L': 2})
[('D', 5), ('A', 4), ('F', 4), ('J', 4)]
('A', 4)
('D', 5)
('F', 4)
('K', 3)
('J', 4)
('L', 2)
('S', 4)

2.有序字典(orderedDict ) 是对字典类型的补充,他记住了字典元素添加的顺序
举例:
import collections #导入模块
dic = collections.OrderedDict() #设置dic为有序字典
#dic = dict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
dic['k3'] = 'k3'
print(dic)
dic.popitem() #去掉最后一个加入的
dic.pop('k2') #去除后可以复制的用
dic.setdefault('k3')
print(dic)
执行结果:
C:\Python34\python.exe E:/Python/S12/day1/test1.py
OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'k3')])
OrderedDict([('k1', 'v1'), ('k3', None)])
转载应用:
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
#按key排序
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
#按value排序
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
#按key的长度排序
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)
3.默认字典(defaultdict) 是对字典的类型的补充,他默认给字典的值设置了一个类型。
import collections
dic = collections.defaultdict(list)
在字典默认情况下,若值为空是不能使用append等参数直接添加的,需要创建后才能添加,而默认字典就解决了这个功能。
举例:
1).在没有使用默认字典情况下
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = {}
for value in values:
if value>66:
if 'k1' in my_dict.keys():
my_dict['k1'].append(value)
else:
my_dict['k1'] = [value]
print(my_dict)
else:
if 'k2'in my_dict.keys():
my_dict['k2'].append(value)
else:
my_dict['k2'] = [value]
print(my_dict)
2).使用defaultdict 后整体的变成这样了:
from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list)
for value in values:
if value>66:
my_dict['k1'].append(value)
else:
my_dict['k2'].append(value)
5.可命名元组(namedtuple)
根据nametuple可以创建一个包含tuple所有功能以及其他功能的类型。
默认元组是根据索引去访问的。
例如:
t = (11,22,33,44)
默认访问方法 t[0] 为11
import collections
MytupleClass = collections.namedtuple('MytupleClass',['x', 'y', 'z'])
#相对于自己自定义了一个类模块
obj = MytupleClass(11,22,33) #一次赋值,主要mytupleCleass有几个元素,这里就需要有几个。否则无法执行
print(obj.x)
print(obj.y)
print(obj.z)
执行结果:
11
22
33

6.队列 双向队列(deque),一个线程安全的双向队列
6.1 双向队列
创建Deque序列:
from collections import deque
d = deque()
Deque提供了类似list的操作方法:
d = deque()
d.append('1')
d.append('2')
d.append('3')
len(d)
d[0]
d[-1]
输出结果:
1
2
3
3
'1'
'3'
两端都使用pop:
d = deque('12345')
len(d)
d.popleft()
d.pop()
d
输出结果:
5
'1'
'5'
deque(['2', '3', '4'])
限制deque的长度:
d = deque(maxlen=30)
当限制长度的deque增加超过限制数的项时, 另一边的项会自动删除:
d = deque(maxlen=2)
d.append(1)
d.append(2)
d
d.append(3)
d
deque([1, 2], maxlen=2)
deque([2, 3], maxlen=2)
添加list中各项到deque中:
d = deque([1,2,3,4,5])
d.extendleft([0])
d.extend([6,7,8])
d
输出结果:
deque([0, 1, 2, 3, 4, 5, 6, 7, 8])

6.2 单项队列(先进先出 FIFO )
import Queue
Queue.Queue
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: