Python的数据结构,常用的list,array,tuple,dict,view,set
[a]*n 复制制成n个列表a [a,a...a,a]
[a]+[b] 连接多个列表 [a,b]
list("x") 将序列类型或迭代器转换为列表 [x]
[x for x in range(3)] 生成器表达式 [0,1,2]
l.append("x") 追加元素x [l,x]
l[:] 切片
l.index("x",n) 从指定位置n查找元素x,返回序号
l.count("x") 统计列表l内的元素x有多少项
l.insert(n,x) 在指定位置n插入元素x
l.extend(l2) 列表l合并列表l2 [l,l2]
l.remove(x) 移除列表l内第一个元素x
l.pop(n) 弹出指定位置的元素(默认为最后项)
l.sort() 将当前列表进行元素整理,数字在前,大写在小写前
bisect.insort(l,x) 向有序列表l中插入元素x
列表用realloc()调整指针数组内存大小,可能需要复制数据。插入和删除操作,还会循环移动后续元素。这些都是潜在的性能隐患。对于频繁增删元素的大型列表,应该应该考虑用链表等数据结构代替。
某些时候,可以考虑用数组代替列表。和列表存储对象指针不同,数组直接内嵌数据,既省下了创建对象的内存开销,又提升了读写效率。
数组array操作()
a = array.array("x",range(3)) 用其他序列类型初始化数组 array('l',[0,1,2])
a.tolist() 转化为列表
a.fromstring("x") 从字符串添加元素x
a.fromlist(list("x")) 从列表添加元素x
a.extend(array.array(a,b)) 合并列表或者数组
元组tuple()
1、只读对象,元组合元素指针数组内存是一次性连续分配的。
2、虚拟机缓存n个元素数量小于20的元组复用对象。
应该竟可能用元组代替列表。除了内存复用更搞笑外,其只读特征更利于并行开发。
s=tuple(x) 将其他序列类型转换成元组
s.count(a) 统计元组s内的元素a
s.index(a) 查找元素a,并返回序号
字典dict{}采用开放地址法的哈希表实现
1、自带元素容量为8的smalltable,只有“超出”时才到堆上额外分配元素表内存。
2、虚拟机缓存80个字典复用对象,但在堆上分配的元素表内存会被释放。
3、按需动态调整容量。扩容或收缩操作都将重新分配内存,重新哈希。
4、删除元素操作不会立即收缩内存。
{} 空字典
dict(zip("ab",range(2))) {'a':0,'b':1}
dict(map(None,"abc",range(2))) {'a':0,'c':None,'b':1} 类似bc操作中,c都在b前面,其他按序排列
dict.fromkeys("abc",1) {'a':1,'b':1,'c':1}
{k:v for k,v in zip("abc",range(3))} {'a':0,'c':2,'b':1}
"x" in d 判断元素x是否在字典d内
del d["x"] 删除元素x
d.update({...}) 合并字典(不排序)
d.pop("x") 弹出value
d.popitem() 弹出(key,value)
d.get("x") 获取value对应的key,若没有则返回None
d.get("x",123) 如果没有key,返回缺省值123
d.setdefault("a",100) 若key存在,直接返回key,否则返回100
对于大字典,调用keys(),value),items()会构造同样巨大的列表,建议用迭代器替代,以减少内存开销。
for k,v in d.iterkeys();d.itervalues();d.iteritems()等等
视图,判断两个字典的差异。
字典:d1,d2
v1=d1.viewitems(),v2=d2.viewitems()
v1&v2得到交集
v1|v2得到并集
v1-v2得到差集
v1^v2对称差集(不会同时出现在v1,v2中)
('a',1) in v1判断是否在v1内
视图让某些操作变的更加简便,比如在不引入新数据项的情况下更新字典内容。
例如:a=dict(x=1)
b=dict(x=10,y=20)
a.update({k:b[k] for k in a.viewkeys() & b.viewkeys()})
a则变为}{'x':10}
集合set用来存储无序不重复对象。所谓不重复对象,除了补水同一对象外,还包括“值”不能相同。集合只能存储可哈希对象,一样有只读版本frozenset。
判重公式:(a is b) or (hash(a) == hash(b) and eq(a,b))
在内部实现上来说,集合和字典非常的相似,除了entry没有value字段。集合不是序列类型,不能像列表那样按序号访问,也不能做切片操作。
集合和字典、列表最大的不同除了元素不重复外,还支持集合运算。
集合和字典主键都必须是可哈希类型对象,但常用的list、dict、set、defaultdict、OrderedDict都是不可哈希的,仅有tuple、frozenset可用。
如果想把自定义类型放入集合,需要保证hash和equal的结果都相同才能去重。