数据结构
Tuple ( )
有序(不同顺序为不同tuple),不可更改, 可index
mytuple = ("apple", "banana", "cherry")
>>>tuple([1,2,3,4])
(1, 2, 3, 4)
>>> tuple({1:2,3:4}) #针对字典 会返回字典的key组成的tuple
(1, 3)
>>> tuple((1,2,3,4)) #元组会返回元组自身
(1, 2, 3, 4)
元组中只包含一个元素时,需要在元素后面添加逗号来消除歧义
tup1 = (50,);
元组中的元素值是不允许修改,不可add,不可insert,但我们可以对元组进行连接组合
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
# 以下修改元组元素操作是非法的。
# tup1[0] = 100;
# 创建一个新的元组
tup3 = tup1 + tup2;
print tup3;
#以上实例输出结果:
#(12, 34.56, 'abc', 'xyz')
元组中的元素值是不允许删除,但我们可以使用del语句来删除整个元组
del tup;
tuple和list非常类似,但是tuple一旦初始化就不能修改, 为tuple不可变,所以代码更安全。
Set { }
无序(顺序怎样都没所谓),不可indexed,元素不重复
myset = {"apple", "banana", "cherry"}
or
myset = set("apple", "banana", "cherry")
空set要用set(),因为{ }是字典
mySet = set()
两个集合间的运算.
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # 集合a中包含而集合b中不包含的元素
{'r', 'd', 'b'}
>>> a | b # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}
add
s.add( x )
update. 参数可以是列表,元组,字典等
s = {11, 22, 33}
s.update({1, 2, 4})
>> {33, 1, 2, 4, 22, 11}
s = {11, 22, 33}
s.update("abcde")```
>> {33, 'd', 11, 'b', 22, 'c', 'e', 'a'}
s = {11, 22, 33}
s.update([9, 10], [99, 11])
>> {33, 99, 9, 10, 11, 22}
不管update是什么数据类型,全部拆开一起放入集合中(同时去重)
remove
s.remove(x)
Dictionary
键必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
d = {key1 : value1, key2 : value2, key3 : value3 }
删除字典元素
del dict['Name'] # 删除键 'Name'
dict.clear() # 清空字典
del dict # 删除字典
键值对
# 取所有键
for key in d.keys()
# 取所有值
for val in d.values()
# 取所有键值对
for key, val in d.items()
get指定键的值(不改变字典)
d.get("想要的那个键","如果没有对应键返回的参数")
pop 返回并从字典删除这个键值对
d.pop("想pop的的键值对的键", "如果没有的返回值")
List [ ]
list = [] ## 空列表
list.append('Google') ## 使用 append() 添加元素
insert
list.insert(i, elem) # insert after i-th item (it becomes the i+1-th tiem)
Heap(堆)
https://leetcode-cn.com/leetbook/read/heap/evmih5/
堆的特性:
- 完全二叉树
- 每个节点的值 <= (最小堆) 或者 >= (最大堆) 孩子节点的值
堆 具有以下的特点:
- 堆 中插入元素 – O(logN)
- 堆 中删除元素 – O(logN)
- 获取 堆 中的最大值或最小值 – O(1)
- 创建堆 – O(N)
完全二叉树如何储存在数组中
- 根节点在第一个元素
- 找父节点:n -> n / 2
- 孩子:n -> n * 2 & n * 2 + 1
- 是否是叶子节点:N(总共有多少个节点) / 2. n > N/2的就是叶子节点
P.S. n代表节点在数组中储存的index
Python实现堆
heapq
堆操作函数模块,使用列表来表示堆对象本身。最小堆,保证最小的元素位于索引0处
函数 | 功能 |
---|---|
heapify(heap) | 让列表具备堆特征 |
heappush(heap, x) | 将x压入堆中 |
heappop(heap) | 从堆中弹出最小的元素 |
heapreplace(heap, x) | 弹出最小的元素,并将x压入堆中(heappop + heaqpush) |
nlargest(n, iter) | 返回iter中n个最大的元素 |
nsmallest(n, iter) | 返回iter中n个最小的元素 |
- 创建堆
import heapq
# 创建一个最小堆
minHeap = [3, 1, 2, 4]
heapq.heapify(minHeap) # 堆化
# 创建最大堆
# python没有内置函数创建最大堆
# 将[每个元素*-1],再将新元素集进行「堆化」操作。
# 此时,堆顶元素是新的元素集的最小值,也可以转换成原始元素集的最大值。
maxHeap = [1,2,3]
maxHeap = [-x for x in maxHeap]
heapq.heapify(maxHeap)
- 获取堆顶元素
# 最小堆获取堆顶元素,即最小值
minHeap[0]
# 最大堆获取堆顶元素,即最大值元素乘以 -1
maxHeap[0]*-1
- 删除堆顶元素
heapq.heappop(minHeap)
Python内存管理
https://www.cnblogs.com/CBDoctor/p/3781078.html
-
引用计数:
变量更像是附在对象上的标签(和引用的定义类似)。当变量被绑定在一个对象上的时候,该变量的引用计数就是1,(还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为0的时候,该对象就会被回收。 -
垃圾回收:
- 当内存中有不再使用的部分时,垃圾收集器就会把他们清理掉。它会去检查那些引用计数为0的对象,然后清除其在内存的空间。当然除了引用计数为0的会被清除,还有一种情况也会被垃圾收集器清掉:当两个对象相互引用时,他们本身其他的引用已经为0了。
- 垃圾回收机制还有一个循环垃圾回收器, 确保释放循环引用对象(a引用b, b引用a, 导致其引用计数永远不为0)。
- 内存结构
https://zhuanlan.zhihu.com/p/148165365
- 池
- 块
- Arenas
self
https://blog.csdn.net/xrinosvip/article/details/89647884
由于类 可以起到模板的作用,故在创建实例的时候,可以将我们认为必须绑定 属性 强制填写进去,在 python中,是通过 类中通常都会使用的一个方法,即def init(self) 方法,在创建实例变量的时候,就把 name 和 score 等属性绑上去。
class Person(object):
def __init__(self,name,score):
self.name = name
self.score = score
student = Person('Gavin',100) # 传入 __init__ 方法中需要的 参数
注意:
1、init 方法的第一个参数永远是 self ,表示创建的实例本身,因此,在 init 方法的内部,就可以把各种属性绑定到 self,因为 self 就指向创建的 实例本身
2、使用了 init 方法,在创建实例的时候就不能传入空的参数了,必须传入与 init 方法匹配的参数,但是 self 不需要传,python解释器会自己把实例变量传进去
与普通的函数相比,在类中定义的函数只有两点点不同:
1、第一个参数永远是 self ,并且调用时不用传递该参数
2、在类中函数相互调用要加 self ,如上例中: c = self.add()+self.square(), 不加 self ,会报错: 函数未定义
3.、self.z = z
将非实例变量实例化,其他函数内就可以调用该实例变量。
除此之外,类的方法和普通函数没甚区别,当然也可以使用 默认参数、可变参数和关键字参数,例子如下:
class Person(object):
def __init__(self,x,y):
self.x = x
self.y = y
def add(self,z=16): # 设置默认变量 z =16,这只是个普通的局部变量,非实例变量,实例变量需要 self.z = z
sum = self.x + self.y + z
return sum
self代表类的实例,而非类;self 就是 对象/实例 属性集合
可以把 self 理解成存储 实例化对象属性的字典(dict), self 存储属性,而没有动作执行
lambda
是一个小型无名函数,可以接受任何数量的参数(argument),但是只能有一个表达式(expression)
lambda arguments : expression
x = lambda a, b, c: a + b + c
print(x(5, 6, 2))
>> 13
可以扩展函数接收的参数个数
def myfunc(n):
return lambda a : a^2 + n
mydoubler = myfunc(2)
print(mydoubler(11))
>> 15