列表
列表是Python中最具有灵活性的有序集合对象类型,与字符串不同的是,列表可以包含任何种类的对象:数字、字符串、甚至是列表。同样,与字符串不同的是,列表是可变对象,他们都支持在原处修改的操作,同样列表的长度是可变的。
可变:列表空间中,所存储并指向某个数据对象的地址是可变的
同意列表中的元素是同类型的
而且列表中存的是地址并不是实际的直接操作数(可变的本质)
列表的创建方式
直接指定元素
>>> [1,2,3,4,5]
>>> l = [1,2,3,4,5]
指定长度但不指定元素,相当于创建一个长度为n但不存任何数据对象地址的空列表
>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]
通过list函数将其他的数据转换为列表,这些数据必须是可迭代的,可迭代的就是可以被for循环操作
>>> list() # 得到一个长度为0的列表
[]
>>> l = list()
>>> len(l)
0
>>> l = list("abcd")
>>> l
['a', 'b', 'c', 'd']#多字符串列表
>>> l[0]
'a'
>>> l[-1]
'd'
>>> l = list(range(0,5))
>>> l
[0, 1, 2, 3, 4]
>>> l =list(1234)#数字不可迭代
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
列表的特有操作
-
修改元素
>>> l [0, 1, 2, 3, 4] >>> l[0]=5 >>> l [5, 1, 2, 3, 4]
-
切片修改
>>> l = [1,2,3,4,5,6,7,8,9] >>> l [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l[3:7] = [666,888,999] >>> l [1, 2, 3, 666, 888, 999, 8, 9]#修改了元素和长度
-
删除操作
>>> l [1, 2, 3, 666, 888, 999, 8, 9] >>> del l[3] >>> l [1, 2, 3, 888, 999, 8, 9] >>> del l[-3] >>> l [1, 2, 3, 888, 8, 9] >>> del l # 删除列表对象 连着变量也一同删除 >>> l Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'l' is not defined
列表的内置函数
-
append():在列表的表尾添加一个元素对象(啥都能加)
>>> l = [1,2,3] >>> l.append(4) >>> l [1, 2, 3, 4] >>> l1 = [1,2,3,4] >>> l2 = [5,6,7,8] >>> l1.append(l2) >>> l1 [1, 2, 3, 4, [5, 6, 7, 8]] >>> l1.append("abc") >>> l1 [1, 2, 3, 4, [5, 6, 7, 8], 'abc']
-
clear():清空列表,不代表删除列表对象
>>> l.clear() >>> l []
-
copy():复制一份新的列表对象,与原列表内容一致,将新列表的地址返回
>>> l1 = [1,2,3,4] >>> l2 = l1 >>> l2[0] = 5 >>> l1 [5, 2, 3, 4] >>> l2 = l1.copy() >>> l1 [5, 2, 3, 4] >>> l2 [5, 2, 3, 4] >>> l2[0]=10 >>> l1 [5, 2, 3, 4] >>> l2 [10, 2, 3, 4]
-
count():计算某个元素在列表出现的次数
>>> l = [1,1,2,3,1,2,3,4,3,2,1,1,2] >>> l.count(2) 4
-
extend():将其他列表的内容扩展到当前列表中(将后者内部所有的元素依次添加在当前列表中)
>>> l1 = [1,2,3,4] >>> l2 = [5,6,7,8] >>> l1.append(l2) >>> l1 [1, 2, 3, 4, [5, 6, 7, 8] ] >>> l1.extend(l2) >>> l1 [1, 2, 3, 4, 5, 6, 7, 8] >>> l2 [5, 6, 7, 8] >>> l1.extend("abc") >>> l1 [1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b', 'c'] >>> l1.extend(123) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not iterable
#如何理解extend? lst = [] def extend(lter): for i in Iter: lst.append(i)
不同于两个序列相加,两个序列相加,是直接创建新的序列对象的(原先的两个对象没变)
-
index():从左到右返回元素的角标,如果不存在则抛出异常
>>> l = [1,2,3,4] >>> l.index(3) 2 >>> l.index(5) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 5 is not in list >>> l.find(3)#字符串有,但列表没有find功能 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list' object has no attribute 'find'
-
insert():在某个位置插入元素,角标如果越界,如果是负数,则为倒数第几个;如果角标大于列表长度,在末尾添加
>>> l [1, 2, 3, 4] >>> l.insert(2,5) >>> l [1, 2, 5, 3, 4] >>> l.insert(10,6) >>> l [1, 2, 5, 3, 4, 6] >>> l.insert(-2,7) >>> l [1, 2, 5, 3, 7, 4, 6]
-
pop():在列表的尾部删除一个元素,弹栈;append理解为进栈
>>> l = [1,2,3,4] >>> l.append(5) >>> l [1, 2, 3, 4, 5] >>> l.pop() 5 >>> l [1, 2, 3, 4]
-
remove():删除从左到右第一个指定的元素(≠角标)
>>> l [1, 2, 3, 4] >>> l.remove(4) >>> l [1, 2, 3] >>> l.remove(2) >>> l [1, 3] >>> l = [1,1,1,2,2,3,3] >>> l.remove(1) >>> l [1, 1, 2, 2, 3, 3]
-
reverse():反转列表
>>> l.reverse() >>> l [3, 3, 2, 2, 1, 1]
-
sort():排序
>>> l = [3,2,9,1,6,5,7,4,8] >>> l.sort() >>> l [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l.reverse() >>> l [9, 8, 7, 6, 5, 4, 3, 2, 1]
作业74-80题
列表解析式
是通过for循环语句来创建列表
>>> l1 = [1,2,3,4,5,6,7,8,9,10]
>>> l1 = list(range(1,11))
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> l1 = [x for x in range(1,11)]
>>> l1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> l1 = list(range(2,11,2))
>>>l1
[2, 4, 6, 8, 10]
>>> l1 = [x for x in range(2,11,2)]
>>> l1
[2, 4, 6, 8, 10]
>>> l1 = [x for x in range(1,21) if x%3==0 ]
>>> l1
[3, 6, 9, 12, 15, 18]
>>> l2 = [x/2 for x in l1]
>>> l2
[1.5, 3.0, 4.5, 6.0, 7.5, 9.0]
二分查找算法
前提是我们的序列必须有序的(递增,递减)
顺序查找的时间复杂度为O(n),二分查找的时间复杂度O(log2(n))
常见时间复杂度排序:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
# 二分查找
def binarySearch(lst, key):
min_index = 0
max_index = len(lst) - 1
mid_index = (min_index + max_index) // 2
while lst[mid_index] != key:
if lst[mid_index] < key:
min_index = mid_index + 1
elif lst[mid_index] > key:
max_index = mid_index - 1
if min_index > max_index:
return -1
mid_index = (min_index + max_index) // 2
return mid_index
lst = [x for x in range(1,13)]
print(binarySearch(lst,9))
print(binarySearch(lst,1))
print(binarySearch(lst,8.5))
print(binarySearch(lst,15))
lst = [x ** 2 for x in range(1,13)]
print(binarySearch(lst,121))
print(binarySearch(lst,120))
选择排序算法
def selectionSort(lst):
for i in range(len(lst) - 1):
for j in range(i+1,len(lst)):
if lst[i] > lst[j]:
lst[i],lst[j] = lst[j],lst[i]#python特色
"""
temp = lst[i]
lst[i] = lst[j]
lst[j] = temp
"""
lst = [5,1,9,8,2,6,7,4,3]
selectionSort(lst)
print(lst)
冒泡排序算法
def bubbleSort(lst):
for i in range(len(lst) - 1):
for j in range(len(lst) - 1 - i):
if lst[j] > lst[j + 1]:
lst[j], lst[j + 1] = lst[j + 1], lst[j]
lst = [5,1,9,8,2,6,7,4,3]
bubbleSort(lst)
print(lst)
选择排序与冒泡排序之比较
- 选择排序每次比出来是固定位置不变,一般是依次得到最小值到最大值的顺序,比完之后值入位。
- 选择排序是依次与固定位置,冒泡是相邻比较,然后是否交换,一直换到最后一个(最后一个还没比较过的)。
- 冒泡排序一般是依次得到最大值到最小值的顺序。
插入排序算法
不需要全比较
def insertionSort(lst):
for i in range(1,len(lst)):#进入某次大轮
e = lst[i]
j = i
while j > 0 and lst[j - 1] > e:#左边有数,且右边数比左边小,就将左边的往右挪一个
lst[j] = lst[j - 1]
j -= 1
lst[j] = e#挪完之后,插入,再进入下一大轮
lst = [5,1,9,8,2,6,7,4,3]
insertionSort(lst)
print(lst)
计数排序算法
def countingSort(lst):
minVal = min(lst)
maxVal = max(lst)
temp = [0] * (maxVal - minVal + 1)#创建等长数组,默认值为0
offset = minVal
for number in lst:
temp[number - offset] += 1#把每个数字出现的次数给统计出来
i = 0
for index in range(len(temp)):
for k in range(temp[index]):#出现的次数,是计数数组里的元素
lst[i] = index + offset#将值放入原先数组里,对其进行更改
i += 1
lst = [5,1,9,8,2,6,7,4,3]
countingSort(lst)
print(lst)
比不了小数,字符串,只能比整数
基数排序算法
按个、十、百位顺序进行排序
:#定义放入哪个容器的函数结构
#1个位 2十位 3百位
#-1 -2 -3(倒数第几位)
if len(str(num)) < r:
return 0
return int(str(num)[-r])#取str(num)的中对应位数的数值
def radixSort(lst):
maxVal = max(lst)
radix = len(str(maxVal))#确定轮数是一共有几轮(几位就几轮)
temp = [None] * 10#定义10个容器,0~9
for i in range(10):
temp[i] = []#将每一个容器都定义为一个链表
#此处注意,如果写成temp =[[]]*10的话那么是把里面的[]链表的首地址放入外面的[]的每一个里面(放了十次,每列操作的是同一组数据),会出错
# 1个位 2十位 3百位
for r in range(1,radix + 1):#个、十、百位都遍历
for num in lst:#原列表中每个数都遍历一遍(放入容器)
temp[getIndex(num,r)].append(num)#拿到对应列表附加一个
i = 0
for k in range(len(temp)):
if len(temp[k]) != 0:#容器为空就不管,不空就遍历取数
for j in range(len(temp[k])):
lst[i] = temp[k][j]
i += 1
temp[k].clear()
lst = []
for i in range(20):
lst.append(random.randint(1,300))
radixSort(lst)
print(lst)
目前为止,可以做完全部的题,以及刷力扣上相关数组,列表的题。、
任重道远,加油加油(ง •_•)ง!