random
使用list之前先学习一下random的使用。
1 | import random |
针对list的一些操作
判断两个list是否有重叠
1 | def get_overlap_list(): |
此处判断的是list,其实换成tuple也是一样的。
list去重
1 | s = ['c', 'a', 't', 'd', 'o', 'g', 'r', 'a', 'b', 'b', 'i', 't'] |
遍历原始list,如果元素不属于新的list则插入
生成26个小写字母的list
1 | chars = [chr(i) for i in range(97,123)] |
使用chr(ASSII)
来定位字母
反转
1 | # 反转 |
主要逻辑是使用insert插入到下标为0的元素,相当于遍历一遍从头开始插入。
判断对称
1 | def get_symmetry_list(): |
此处判断是否对称主要取决于元素个数是否为奇数,也就是range的次数。
取出字符串最长的单词
1 | def get_word_list(): |
列表按绝对值排序
1 | num_list = [1, -6, 2, -5, 9, 4, 20, -3] |
在冒泡的方式排序的过程使用abs()
获取绝对值。
生成列表解析式 1-10之间的偶数
1 | [i for i in range(10) if i % 2 == 0] |
元素除以2为0则是偶数。
找出最大元素的下标
1 |
|
list 组合为string
1 | l = [1, 2, 3, 5, 6] |
str.join(item) join 函数是一个字符串操作函数。item表示一个成员,且只能有一个。上述代码中''.join(xxx)
含义是将字符串中的xxx以字符分割后再拼接为一个字符串,代码中为空,因此输出字符串中也无间隔。
其他示例:
1 | l = [1, 2, 3, 5, 6] |
合并两个list为dict
1 | def list2dict(): |
zip的方式:
1 | a = ["a", "b", "c"] |
zip 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成多个tuple,然后返回由这些tuple组成的list。但是要注意版本区别,Python 2.0 返回的是list,Python 3.0 返回的是一个对象,需要手动list()转换:
1 | # python 2.0+ |
dict()函数用于创建一个字典。
1 | # 语法 |
使用方法:
1 | >>>dict() # 创建空字典 |
深浅拷贝
这里来讲述一下深拷贝和浅拷贝。
变量存储在栈内存,对象存储在堆内存。
浅拷贝只对源对象的引用进行拷贝,对象的内容不进行操作。实现原理:
- 对于源对象是可变数据类型,在堆内存中创建新空间;
- 对于源对象不是可变数据类型,则拷贝起引用。
可变数据类型包括:List、Dictionary、
不可变数据类型包括:String、Number、Tuple
浅拷贝
- 不拷贝子对象的内容,只拷贝子对象的引用
- 可以使用内置函数
copy()
1 | # 单层浅拷贝-源对象是可变数据类型 |
对于源对象是可变数据类型,在堆内存中创建新空间。
深拷贝
- 会连子对象的内存全部拷贝一份,对子对象的修改不会影响资源对象
- 可以使用内置函数
deeocopy()
源对象是不可变数据类型
1 | # 单层浅拷贝-源对象是不可变数据类型 |
总结
深浅拷贝都是对源对象的复制。
冒泡排序
1 | num_list = [23, 54, 56, 7, 12, 354, 56, 77, 12, 4, 2] |
- 首先第一层循环list;
- 第二层循环list,范围为list总长度-1-当前元素(元素下标都是从0开始)
- 如果该元素小于下一个元素
- 赋值 元素=下一个元素,下一个元素=该元素 (当前元素和下一个元素进行调换)
- 如果该元素小于下一个元素
- 第二层循环list,范围为list总长度-1-当前元素(元素下标都是从0开始)
最后输出新的list就是排序后的list,从大到小。并且该算法还有两个规律:
- 循环总次数等于元素个数之和,比如10个元素需要55次、11个元素需要66次等等。
- 切换一下判断条件可以直接改为从小大排序,
if num_list[j] > num_list[j + 1]:
二分法查找
所谓二分法查找针对的是一个有序的数据集合,每次通过跟区间中的元素对比,将待查找的区间缩小为之前的一半,知道找到要查找的元素,或者区间缩小为0.
示例
1 | array = [0, 0, 1, 1, 3, 3, 4, 4, 6, 7, 12, 14, 15, 17, 19, 25, 30, 32, 33, 43, 44, 47, 50, 54, 61, 62, 66, 72, 77, 80, 91, 97, 102, 107, 110, 113, 118, 123, 126, 130, 142, 143, 144, 145, 148, 152, 158, 162, 177, 179, 184, 196, 198, 198, 200, 212, 212, 218, 236, 259, 266, 290, 298, 304, 310, 311, 338, 347, 349, 350, 365, 377, 381, 389, 389, 395, 404, 408, 431, 446, 466, 480, 496, 503, 521, 528, 531, 555, 570, 576, 593, 625, 681, 687, 723, 818, 835, 844, 853, 854] |
限制
容易出错的地方:
- mid的取值,mid=(low+high)/2 这种写法是有问题的。因为如果 low 和 high 比较大的话,两者之和就有可能会溢出。正确的方法可以改为
middle=low+(height-low)//2
或者middle=low+((height-low)>>1)
(除以2的1次方); - low和height的更新要使用
height = middle-1
和low = middle+1
。
>>
右移,右边的数字指定了移动的位数,除法 。print(a >> 3) # 相当于a 除 2的3次方<<
左移,左边的数字指定了移动的位数,乘法。print(a << 3) # 相当于a 乘 2的3次方
局限性:
- 只能查找有序的数据集;
- 针对的是静态有序数据集;
- 不适合数据量太大或太小的场景。太大的情况会消耗太多内存,太小的场景和遍历差别不大。