对象函数 必须通过某一个具体的对象来调用 列表.函数名()
# append()
# 将某一个元素对象添加在列表的表尾
# 如果添加的是其他的序列,该序列也会被看成是一个数据对象
arr = [1,2,3,4]
arr.append(5)
print(arr)
arr2 = [6,7,8]
arr.append(arr2)
print(arr)
# count()
# 统计列表当中 某一个元素出现的次数
arr = [1,2,3,4,1,2,3,1,1,2,0,0,1]
print(arr.count(1))
# extend()
# 在当前列表中 将传入的其他序列的元素添加在表尾
arr1 = [1,2,3]
arr2 = [4,5,6]
arr1.extend(arr2)
print(arr1)
"""
arr1.extend(7)
TypeError: 'int' object is not iterable(可迭代的=序列)
"""
arr1.extend("ABC")
print(arr1)
# index()
# 查找(从左到右)元素第一次出现的位置(角标)
arr = [1,2,3,4,5,6,7,4,5,6,9]
print(arr.index(4))
print(arr.index(4, 5, 8)) #[5, 8) 区间中找4的角标
"""
print(arr.index(10))
ValueError: 10 is not in list 找不到则报错
"""
# insert(index, obj)
# 在某一个角标出处插入一个元素
arr = [1,2,3,4]
arr.insert(2, 5)
print(arr)
# pop()
# 弹栈:删除最后一个元素 并返回其值
# 也可以删除指定角标处的元素
arr = [1,2,3,4]
print(arr.pop())
print(arr)
print(arr.pop(1))
print(arr)
# remove()
# 移除指定元素 从左到右第一次出现的
arr = [1,2,3,4,2,3,4,2,3,4]
arr.remove(4)
print(arr)
# reverse()
# 翻转列表
arr = [1,2,3,4]
arr.reverse()
print(arr)
# sort()
# 排序
arr = [4,2,5,2,6,2,7,9,4,7,2,7]
# arr.sort() # 默认升序
arr.sort(reverse = True) # 降序
arr = ["ABC", "123123123","我爱你中国","123123123","kasdkjas"]
arr.sort(key = len) # 以序列的长度为基准进行排序
print(arr)
# clear()
# 清空
arr = [1,2,3,4]
arr.clear()
print(arr)
# copy()
# 复制一个列表(浅拷贝)
arr1 = [1,2,3,4]
arr2 = arr1.copy()
print(arr1 == arr2) # True 比较的是内容
print(arr1 is arr2) # False 比较的是对象地址
print(arr1)
print(arr2)
arr1[0] = 5
print(arr2[0])
# 上述代码在arr1中修改元素 并不影响arr2
arr1 = [1,2,3,[4,5,6]]
arr2 = arr1.copy()
arr2[0] = 7
print(arr1[0])
print(arr2[0])
arr2[3][0] = 666
print(arr1[3])
# 上述代码在arr2中修改元素 影响arr1
arr2[3] = [9,9,9]
print(arr1[3])
print(arr2[3])
# 额外的知识
# del关键字:删除
arr = [1,2,3,4]
del arr[0] # 删除序列中的元素
print(arr)
del arr # 删除变量
"""
NameError: name 'arr' is not defined. Did you mean: 'arr2'?
print(arr)
"""
>>> arr = [1,2,3]
>>> arr[0] = 4
>>> arr
[4, 2, 3]
>>> s = "ABC"
>>> s[0]
'A'
>>> s[0] = "D"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
字符串对象不支持元素修改
# center()
# 指定填充字符 将目标字符进行居中
s1 = "ABC"
s2 = s1.center(10,"#")
print(s1)
print(s2)
# count()
# 和列表的count相似 统计字符串的个数
s = "abchjghjabcjkhjkhabchkjhabc"
print(s.count("abc"))
print(s.count("a"))
# count是非贪心统计 贪心统计6个
s = "AAAAAAAA"
print(s.count("AAA"))
print(s.count("AAA",2,6))
# endswith()
# 过滤字符串结尾 同样也可以指定区间
s = "带土.img"
print(s.endswith(".img"))
# find()
# 寻找字符串第一次出现的位置 同样也可以指定区间
s = "八百标兵奔北坡"
print(s.find("标兵")) # 2 指定是标的角标
# format()
# 格式化输出
name = "小强"
age = 18
print("我的名字叫%s, 年龄%d岁" % (name, age))
print("我的名字叫{}, 年龄{}岁".format(name, age))
print(f"我的名字叫{name}, 年龄{age}岁")
print(f"我的名字叫{3 > 2}, 年龄{2 ** 8}岁")
# index()
# 寻找字符串第一次出现的位置 同样也可以指定区间
s = "八百标兵奔北坡"
print(s.index("标兵")) # 2 指定是标的角标
s = "ABC"
print(s.find("D")) # -1 如果找不到 则返回-1
# print(s.index("D"))# 如果找不到 直接报错 ValueError: substring not found
# isalnum()
# 判断是否是字母或数字字符串 al-alpha 字母 num-number 数字
print("abc".isalnum())
print("123".isalnum())
print("abc123".isalnum())
print("abc123^&%&^&".isalnum())
# isalpha() 是否是纯字母字符串
# isdecimal() 是否是十进制纯数字字符串
# isdigit() 是否是纯数字字符串
# isspace() 是否是纯空格字符串
# islower() 出现的字母是否是小写字母
print("123abc".islower())
print("123Abc".islower())
# isupper() 出现的字母是否是大写字母
# join() 将字符串列表进行拼接的
arr = ["banana", "orange", "apple","pich"]
s = "-".join(arr)
print(s)
# ljust()左对齐 rjust()右对齐
print("ABC".ljust(10, "#"))
print("ABC".rjust(10, "#"))
# lower()出现的大写字母转小写 upper() 相反
print("Hello World123".lower())
# lstrip()去除左边空格 rstrip()去除右边空格
print(" ABC ".lstrip())
print(" ABC ".rstrip())
print(" ABC ".strip()) # 两边都去掉连续空格
print(" A B C ".strip())
# replace(a,b) 替换 a旧 b新
s = "宇智波佐助、宇智波斑、宇智波鼬、宇智波泉奈、宇智波止水、宇智波卡卡西"
s1 = s.replace("宇智波","千手")
print(s)
print(s1)
# split() 以某一个分割符来切割字符串 结果是一个字符串的列表
s = "泰罗-杰克-赛文-迪迦-梦比优斯"
arr = s.split("-")
print(arr)
arr = "1 2 34 4.12".split(" ")
print(arr)
math模块和random模块
# 导入math模块
import math
# Math模块提供了许多数学函数和常量,以下是一些常见的用法:
# 数学常数
pi_value = math.pi # pi_value = 3.141592653589793
e_value = math.e # e_value = 2.718281828459045
# 数学函数
# 平方根
sqrt_result = math.sqrt(16) # sqrt_result = 4.0
# 对数函数
log_result = math.log(10) # log_result = 2.302585092994046
log10_result = math.log10(100) # log10_result = 2.0
# 三角函数
sin_result = math.sin(math.pi/2) # sin_result = 1.0
cos_result = math.cos(math.pi) # cos_result = -1.0
tan_result = math.tan(0) # tan_result = 0.0
# 向上取整
ceil_result = math.ceil(4.3) # ceil_result = 5
# 向下取整
floor_result = math.floor(4.7) # floor_result = 4
# 绝对值
abs_result = math.fabs(-4.5) # abs_result = 4.5
# 阶乘
factorial_result = math.factorial(5) # factorial_result = 120
# 幂运算
power_result = math.pow(2, 3) # power_result = 8.0
# 最大公约数
gcd_result = math.gcd(12, 8) # gcd_result = 4
# 最小公倍数
lcm_result = math.lcm(12, 8) # lcm_result = 24
# 导入random模块
import random
# Random模块提供了生成随机数的功能,以下是一些常见的用法:
# 生成随机整数
random_integer = random.randint(1, 10) # 生成1到10之间的随机整数
# 生成随机浮点数
random_float = random.uniform(1.0, 5.0) # 生成1.0到5.0之间的随机浮点数
# 从列表中随机选择一个元素
my_list = [1, 2, 3, 4, 5]
random_choice = random.choice(my_list) # 从my_list中随机选择一个元素
# 打乱列表顺序
random.shuffle(my_list) # 将my_list中的元素顺序打乱
# 生成随机种子
random_seed = random.seed(10) # 生成随机种子,设置种子值为10
# 生成随机高斯分布数
random_gaussian = random.gauss(0, 1) # 生成均值为0,标准差为1的随机高斯分布数
序列的基本算法:
1.选择排序
选择排序算法的基本原理:
-
选择排序算法是一种简单的排序算法,基本思想是从待排序的数据元素中选择最小(或最大)的一个元素,放到序列的起始位置,然后再从剩余未排序的元素中继续寻找最小(或最大)的元素,依次放到已排序序列的末尾,直到所有元素都排序完毕。
-
选择排序算法的时间复杂度为 O(n^2),其中 n 是待排序元素的个数。这是因为在排序过程中,每一轮内部循环都需要比较未排序序列中的所有元素,因此最坏情况下需要执行 (n-1)+(n-2)+...+1 = n(n-1)/2 次比较操作。
-
选择排序算法是一种稳定的排序算法,即排序前两个相等的数其相对位置在排序后不会发生改变。这是因为在排序过程中,只有当待排序序列中的最小(或最大)元素与当前位置的元素不同时才会进行交换,因此相等的元素不会发生交换,相对位置也不会发生改变。
-
实现代码:
arr = [6, 2, 1, 3, 5, 7, 4, 8, 9] for i in range(len(arr) - 1): # -1 少比较1轮 for j in range(i + 1, len(arr)): if arr[i] > arr[j]: arr[i], arr[j] = arr[j], arr[i] print(arr)
综上所述,选择排序算法是一种简单、稳定但效率较低的排序算法,适用于小规模的数据排序。
2.冒泡排序:
1. 冒泡排序的基本原理是通过相邻元素之间的比较和交换来实现排序。具体而言,算法会多次遍历要排序的元素序列,每次遍历时将相邻的元素进行比较,如果它们的顺序不符合要求(比如升序要求左边的元素小于右边的元素),就交换它们的位置。通过多次遍历和交换,较大(或较小)的元素会逐渐“浮”到数列的顶端,而较小(或较大)的元素则会逐渐沉到底部,从而实现排序的目的。
2. 整个排序过程可以形象地理解为像气泡一样逐渐上浮或下沉,这也是“冒泡排序”名称的由 来。经过若干轮遍历和交换,最终数列就会完成排序。
3.冒泡排序的时间复杂度为 O(n^2),其中 n 是待排序元素的个数。这意味着排序的时间随着元素个数的增加而呈平方级增长,因此在大规模数据的排序场景中不太适用。
4.实现代码:
arr = [6, 2, 1, 3, 5, 7, 4, 8, 9]
for i in range(len(arr) - 1):# -1 少比较1轮
for j in range(len(arr) - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
print(arr)
3.插入排序
插入排序的基本思想是:将一个元素插入到已排好序的元素序列中,从而得到一个新的、元素个数更多的有序序列。具体实现过程如下:
-
从第二个元素开始,依次将每个元素插入到已排序序列的合适位置。第一个元素默认已经是有序的。
-
对于未排序的部分,依次取出一个元素,将它插入到已排序序列中的合适位置,使得插入后仍然保持有序性。
-
在插入的过程中,需要将大于待插入元素的元素往后移动一位,为待插入元素腾出位置。
-
重复以上步骤,直到所有元素都被插入到有序序列中,完成排序。
-
实现代码:
arr = [6, 2, 1, 3, 5, 7, 4, 8, 9] """ for i in range(1, len(arr)): j = i while j > 0 and arr[j - 1] > arr[j]: arr[j], arr[j - 1] = arr[j - 1], arr[j] j -= 1 """ # 优化后的插入排序 for i in range(1, len(arr)): e = arr[i] j = i while j > 0 and arr[j - 1] > e: arr[j] = arr[j - 1] j -= 1 arr[j] = e print(arr)
插入排序的时间复杂度为 O(n^2),其中 n 是待排序元素的个数。最坏情况下,所有元素都需要依次插入到已排序序列的最前面,此时时间复杂度为 O(n^2)。但是,当待排序序列基本有序或者部分有序时,插入排序的时间复杂度会降低到 O(n)。因此,在某些场景下,插入排序可以表现出较好的性能。
4.计数排序
计数排序是一种非比较排序算法,适用于待排序元素范围较小的情况。其基本思想是统计每个元素出现的次数,进而确定每个元素在最终有序序列中的位置。具体步骤如下:
-
找出待排序序列中的最大值和最小值,确定计数数组的范围。在代码中,通过求出最小值和最大值,创建一个临时计数数组 temp,长度为(maxValue - minValue + 1)。
-
遍历待排序序列,统计每个元素出现的次数,存储在计数数组 temp 中对应元素的位置上。例如,对于元素 arr[i],在 temp 中的索引为 arr[i] - minValue。
-
根据计数数组 temp 中的统计信息,重新构造排序后的序列。遍历计数数组,依次将元素放回原始序列 arr 中,根据出现次数的多少,逐个填充到合适的位置。
-
遍历完成后,原始序列 arr 中的元素就按照顺序排列好了。
-
实现代码:
arr = [8,2,1,4,8,7,9,2,3,4] minValue = min(arr) maxValue = max(arr) temp = [0] * (maxValue - minValue + 1) for i in range(len(arr)): temp[arr[i] - minValue] += 1 k = 0 for index in range(len(temp)): while temp[index] > 0: arr[k] = index + minValue k += 1 temp[index] -= 1 print(arr)
计数排序的时间复杂度为 O(n + k),其中 n 是待排序元素的个数,k 是待排序元素的范围大小(最大值与最小值之差加1)。当 k 较小且待排序序列比较集中时,计数排序是一种高效的排序算法。但是,由于其需要额外的空间存储计数数组,因此对于范围较大的待排序序列并不适用。
5.插值查找
插值查找是一种用于在有序数组中搜索指定元素的算法,与二分查找类似,但是针对数据分布比较均匀的情况进行了优化。其基本思想是通过插值来估计查找到的位置,从而更快地缩小搜索范围。
-
计算估计位置:根据待查找的元素值 key 与数组中最小值和最大值的比较,通过插值公式来估算 key 可能处于的位置。
插值公式:mid = (key - arr[low]) / (arr[high] - arr[low]) * (high - low) + low
其中,arr 为有序数组,low 为区间最小值的索引,high 为区间最大值的索引,key 为待查找的元素值。 -
比较估计位置:将估计位置 mid 与实际值进行比较。
- 如果 arr[mid] 等于 key,则表示找到了目标元素,搜索结束。
- 如果 arr[mid] 小于 key,则更新 low 为 mid + 1,缩小搜索范围到 mid 右侧的子数组。
- 如果 arr[mid] 大于 key,则更新 high 为 mid - 1,缩小搜索范围到 mid 左侧的子数组。
-
重复以上步骤,直到找到目标元素或者搜索范围为空。
-
实现代码:
#插值查找 arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] low = 0 high = len(arr) - 1 mid = 0 key = 5.5 while True: mid = int((key - arr[low]) / (arr[high] - arr[low])) * (high - low) + low if high < low: mid = -1 break if mid > high or mid < low: mid = -1 break if arr[mid] == key: break elif arr[mid] > key: high = mid - 1 elif arr[mid] < key: low = mid + 1 print(mid)
-
插值查找与二分查找相比,对于分布比较均匀的有序数组,其能更快地定位到目标元素,但在数据分布不均匀的情况下效果可能并不明显。其时间复杂度为 O(log(log n)),但对于分布不均匀的数据,最坏情况下仍可能达到 O(n)。