Python数据类型认识
列表 list
数据类型list,list是python内置的一种高级数据类型。list是一种有序的集合,基于链表实现 在python中应用很广泛
创建
""" 创建 """
# 用变量 = [] 一定要是英文输入法
list1 = [] # 创建一个空列表 <class 'list'> 列表数据类型
print(type(list1))
# 在 python 里面列表是可以存储所有 python 对象
list2 = [12, 1.0, 'we', True, False, print()]
print(list2)
'''第一种方法,使用中括号[]'''
lst = ['路飞', '索隆', 98]
print(lst) # 结果:['路飞', '索隆', 98]
'''第二种方法,使用内置函数list()'''
lst2 = list(['路飞', '索隆', 98])
print(lst2) # 结果:['路飞', '索隆', 98]
""" 易错点1 """
# 1. 在后续变量的命名的时候,千万不要用类型的关键字命名(int,false,str,list,bool)
list = [1, 4, 5] # 禁止使用关键字命名
# 因为这些关键字在 python 底层中右特殊作用
""" 易错点2 """
name1 = [1, 3, 4, 5]
b = str(name1)
print(b)
# 不能看他的一个表面,要使用 type 进行打印
print(type(b))
# 一定要注意数据类型,根据不同的数据类型在 python 操作不同
列表可以一次性存储多个数据,且可以为不同数据类型
取值
""" 取值 """
name_list = ['正向','无敌','自由','网址','地址','开心','打开']
# 顺序取值,下标从左往右 0 开始
print(name_list[4])
# 逆序取值,下标从右往左 -1 开始
print(name_list[-1])
# 列表索引超出范围 list index out of range
print(name_list[10]) # 报错
修改
# 修改指定下标数据
# 根据索引找到列表中的数据, 可以赋值修改值
# 通过重新赋值从而达到修改的作用
name_list = ['苹果', '香蕉', '芒果', '榴莲', '橘子']
name_list[4] = '广州'
print(name_list) # ['苹果', '香蕉', '芒果', '榴莲', '广州']
切片
""" 切片 """
name_list = ['a','b','c','d','e','f','g']
print(name_list[0:5]) # 取 a 到 e ,他也是一个左闭右开区间
print(name_list[0:]) # 取全部
# 步长
# 不写的话默认为1
# 如果是顺序取值,那么步长一定要为正数
print(name_list[0:4:2])
print(name_list[4:0:-2]) # 正数步长方向也是从左往右,负数步长是从右往左
常用方法
添加 - append()、extend()、insert()
append()
''' append() - 列表结尾追加数据 '''
# 列表序列.append(数据)
name_list = ['苹果', '香蕉', '芒果', '榴莲', '橘子', '西瓜', '哈密瓜']
print(name_list.append('西红柿')) # 是一个添加过程,是由于没有返回值所以返回 None
# 所有的列表变化调用的方法,都是基于列表本身操作
print(name_list) # ['苹果', '香蕉', '芒果', '榴莲', '橘子', '西瓜', '哈密瓜', '西红柿']
name_list.append([1, 2, 3]) # 如果添加的是一个序列那么就是整体添加
print(name_list) # ['苹果', '香蕉', '芒果', '榴莲', '橘子', '西瓜', '哈密瓜', '西红柿', [1, 2, 3]]
extend()
''' extend() - 列表结尾追加数据,如果数据是一个序列,则将这个序列的数据逐一添加到列表 '''
name_list = ['苹果', '香蕉', '芒果', '榴莲']
name_list.extend('西瓜') # 只能添加一个序列
print(name_list) # ['苹果', '香蕉', '芒果', '榴莲', '西', '瓜']
name_list.extend([1, 3, 4, 5]) # 逐一合并添加
print(name_list) # ['苹果', '香蕉', '芒果', '榴莲', '西', '瓜', 1, 3, 4, 5]
insert()
''' insert() - 指定索引位置新增数据,注意索引从0开始 '''
# 列表序列.insert(位置下标(索引),数据)
name_list = ['苹果', '香蕉', '芒果', '榴莲']
name_list.insert(3, '哈密瓜')
print(name_list) # ['苹果', '香蕉', '芒果', '哈密瓜', '榴莲']
删除 - pop()、remove()、del()、clear()
pop()
''' pop() - 删除指定下标的数据(默认为最后一个),并返回该数据 '''
# 列表序列.pop(下标)
name_list = ['苹果', '香蕉', '芒果', '榴莲']
print(name_list.pop()) # 根据索引进行删除,默认删除最后一个元素,一次只能删除一个 # 榴莲
# 删除指定位置的数据
print(name_list.pop(4) # 如果索引不存在 pop index out of range 报错
remove()
''' remove() - 移除列表中某个数据的第一个匹配项 '''
name_list = ['苹果', '香蕉', '芒果', '榴莲']
# 列表序列.remove(数据)
print(name_list.remove()) # 需要给定一个参数,否则报错
print(name_list.remove('香蕉')) # 没有返回值 None
# 数据不存在 报错
name_list.remove('444')
del()
''' del - 指定索引删除数据 '''
# 下标0开始 0,1,2,3
name_list = ['苹果', '香蕉', '芒果', '榴莲']
del name_list[3]
print(name_list) # ['苹果', '香蕉', '芒果']
clear()
清空列表
list1 = ['python', 'java', 'php']
list1.clear()
print(list1) # [] --- 空列表
查找 - index()
index()
''' index() - 返回指定数据所在位置的索引 '''
# 示例
list1 = [41, 2, 111, 100, 6, 2]
print(list1.index(2)) # 如果列表里面有2个一样的数据那么他会返回第一个下标索引 # 1
print(list1.index(9)) # 如果数据不存在就会报错
# 示例
li = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 1, 1, 2, 3]
print(li.index('A')) # 0 # 查找元素A首次出现的索引位置
print(li.index(1)) # 7 # 查找元素1首次出现的索引位置
统计 - count()
count()
''' count() - 统计指定数据在当前列表中出现的次数 '''
# 示例
list1 = [41, 2, 111, 100, 6, 2]
print(list1.count(41)) # 出现 1 次
print(list1.count(2)) # 出现 2 次
print(list1.count(99)) # 统计没有的数据返回0次,不会报错
# 示例
li = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 1, 1, 2, 3]
print(li.count('A')) # 1# 统计元素A出现的次数
print(li.count(1)) # 2 # 统计元素1出现的次数
反转 - reverse()
reverse()
''' reverse() - 把数据反转过来 '''
# 示例
num_list = [1, 5, 2, 3, 6, 8]
num_list.reverse()
print(num_list) # [8, 6, 3, 2, 5, 1]
# 示例
li = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 1, 1, 2, 3]
li.reverse() # 反转列表元素
print(li) # [3, 2, 1, 1, 'G', 'F', 'E', 'D', 'C', 'B', 'A']
复制 - 浅拷贝copy()、深拷贝deep copy()
当我们需要复制这个列表的时候,我们就需要用到copy函数
copy函数分为浅拷贝(shallow copy)和深拷贝(deep copy)
(注:我们并不是在列表的基础上复制元素,而是复制列表,产生了新的列表,我们需要新的列表名来定义)
''' 对象引用 '''
array = [1, 2, 3, 4, 5]
arr1 = array # 通过赋值的方式把对象进行了引用
# 这两个变量任然是同一对象
print(id(array)) # 2881880086208
print(id(arr1)) # 2881880086208
# 修改一个对象值,也导致另一个变量的结果也会改变
array[0] = 'a'
print(array) # ['a', 2, 3, 4, 5]
print(arr1) # ['a', 2, 3, 4, 5]
''' 浅拷贝 '''
# 浅拷贝:数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)
import copy # 深浅拷贝模块,内置对象
array = [1, 2, 3, 4, 5]
# 浅拷贝会新建一个对象,区分原对象
arr1 = copy.copy(array) # 将 array 这个对象完全拷贝一份出来
print(id(array)) # 2881883022336
print(id(arr1)) # 2881883029376
''' 浅拷贝作用域 '''
array2 = [1, ['a', 'b', 'c'], 3]
arr2 = copy.copy(array2)
array2[1][0] = 100
print(array2) # [1, [100, 'b', 'c'], 3]
print(arr2) # [1, [100, 'b', 'c'], 3]
# 浅拷贝仅作用域一维数据,就是没有嵌套
# 如果浅拷贝数据中有嵌套数据,那么拷贝出来的内容中嵌套的数据部分任然指的是同一对象
''' 深拷贝 '''
# 深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)
# 深拷贝就是完完全全复制了一份,且数据不会互相影响,因为内存不共享
# copy.deepcopy 深拷贝,把对象里面各个维度的数据全部拷贝一份,区分原对象
array3 = [1, ['a', 'b', 'c'], 3]
arr3 = copy.deepcopy(array3)
array3[1][0] = 100
print(array3) # [1, [100, 'b', 'c'], 3]
print(arr3) # [1, ['a', 'b', 'c'], 3]
'''
总结:
copy.copy 浅拷贝 - 只拷贝父对象,不会拷贝对象的内部的子对象。
copy.deepcopy 深拷贝 - 拷贝对象及其子对象
'''
排序 - sort()、sorted()
sort()
''' sort() - 排序,他是可以默认升序从小到大进行排列 '''
# 示例
num_list = [1, 5, 2, 3, 6, 8]
num_list.sort()
print(num_list) # [1, 2, 3, 5, 6, 8]
# 改成降序
num_list.sort(reverse=True) # 默认 reverse = True
print(num_list) # [8, 6, 5, 3, 2, 1]
# 示例
li = [1, 5, 2, 99, 6, 44, 66, 3, 34]
li.sort() # 默认对列表数据进行从小到大排序
print(li) # [1, 2, 3, 5, 6, 34, 44, 66, 99]
li.sort(reverse=True) # 对列表数据进行从大到小排序
print(li) # [99, 66, 44, 34, 6, 5, 3, 2, 1]
# 根据对列表元素反转的规律,从大到小排序也可以先sort后再reverse
# li.sort()
# li.reverse()
sorted()
L = [8, 2, 50, 3]
l = sorted(L)
print(l) # [2, 3, 8, 50]
sort ()与sorted()区别
sort() 是应用在 list 上的方法,sorted() 可以对所有可迭代的对象进行排序操作。
list 的 sort() 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted() 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
使用常用的排序算法进行排序
同其他高级函数一样,Python也可以使用算法,利用一般语句进行排序。
一、冒泡排序
冒泡排序是最常见到的排序算法,也是很基础的一种排序算法。它的实现思想是:相邻的两个元素进行比较,然后把较大的元素放到后面(正向排序),在一轮比较完后最大的元素就放在了最后一个位置,像鱼儿在水中吐的气泡在上升的过程中不断变大,
# 冒泡排序
def bubble_sort(alist):
for i in range(len(alist) - 1, 0, -1):
for j in range(i):
if alist[j] > alist[j + 1]:
alist[j], alist[j + 1] = alist[j + 1], alist[j]
return alist
alist = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
res = bubble_sort(alist)
print(res) # [1, 24, 4, 34, 42, 42, 65, 65, 89, 656, 876, 6757]
二、选择排序
选择排序的思路是:第一轮的时候,所有的元素都和第一个元素进行比较,如果比第一个元素大,就和第一个元素进行交换,在这轮比较完后,就找到了最小的元素;第二轮的时候所有的元素都和第二个元素进行比较找出第二个位置的元素,以此类推。
# 选择排序
def select_sort(alist):
for i in range(len(alist) - 1):
min_index = i
for j in range(i + 1, len(alist)):
if alist[j] < alist[min_index]:
min_index = j
if min_index != i:
alist[i], alist[min_index] = alist[min_index], alist[i]
return alist
alist = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
res = select_sort(alist)
print(res) # [1, 24, 4, 34, 42, 42, 65, 65, 89, 656, 876, 6757]
三、插入排序
插入排序的思想是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。 是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置), 而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中
# 插入排序
def insert_sort(alist):
for i in range(1, len(alist)):
for j in range(i, 0, -1):
if alist[j] < alist[j - 1]:
alist[j - 1], alist[j] = alist[j], alist[j - 1]
return alist
alist = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
res = insert_sort(alist)
print(res) # [1, 24, 4, 34, 42, 42, 65, 65, 89, 656, 876, 6757]
四、快速排序
- 快速排序,英文称为Quicksort,又称划分交换排序partition-exchange sort简称快排。
- 快速排序使用分治策略来把一个序列分为两个子序列。首先从数列中挑出一个元素,并将这个元素称为「基准」pivot。重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面,相同的数可以到任何一边。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区partition操作。之后,在子序列中继续重复这个方法,直到最后整个数据序列排序完成。
- 快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn)。事实上,快速排序通常明显比其他算法更快,因为它的内部循环可以在大部分的架构上很有效率地达成。
# 快速排序
def quick_sort(alist, start, end):
if start >= end:
return
pivot = alist[start]
low = start
high = end
while low < high:
while low < high and pivot < alist[high]:
high -= 1
alist[low] = alist[high]
while low < high and alist[low] < pivot:
low += 1
alist[high] = alist[low]
return alist
alist = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
res = quick_sort(alist, 1, 10)
print(res) # [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
五、希尔排序
- 希尔排序也称递减增量排序,是插入排序的一种改进版本,英文称为Shell Sort,效率虽高,但它是一种不稳定的排序算法。
- 插入排序在对几乎已经排好序的数据操作时,效果是非常好的;但是插入排序每次只能移动一位数据,因此插入排序效率比较低。
- 希尔排序在插入排序的基础上进行了改进,它的基本思路是先将整个数据序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录基本有序时,再对全部数据进行依次直接插入排序。
# 希尔排序
def shell_sort(alist):
gap = len(alist) // 2
while gap > 0:
for i in range(gap, len(alist)):
j = i
while (j - gap) >= 0 and alist[j - gap] > alist[j]:
alist[j - gap], alist[j] = alist[j], alist[j - gap]
j -= gap
gap //= 2
return alist
alist = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
res = shell_sort(alist)
print(res) # [1, 4, 24, 34, 42, 42, 65, 65, 89, 656, 876, 6757]
案例 - 列表中是否存在
# 输入要查找的名字,如果在列表里面,就提示 "存在",否则提示 "不存在"
name_list = ['正向', '无敌', '自由', '网址', '地址', '开心', '打开']
name = input('请输入要查找的名字:')
if name in name_list:
print('存在')
else:
print('不存在')
案例 - 收集重复数据
""" 收集一下列表中所有不重复的数据 """
# 进行去重
list1 = [4, 2, 1, 0, 6, 2, 1]
list2 = [] # 定义空列表
for i in list1:
if i not in list2: # 如果数据不存在则添加到列表
list2.append(i)
else:
pass # pass 如果什么都不想做就使用 pass
print(list2)
""" 收集以下列表中所有不重复的数据,找重复数据的索引 """
list1 = [4, 2, 1, 0, 6, 2, 1]
list2 = []
for i in range(len(list1)): # 7 0123456
if list1[i] not in list2: # 如果数据不存在,通过下标取值
list2.append(list1[i])
else:
print(i) # 这个是重复索引
print(list2)
案例 - 随机取整数
"""
随机取10次 1 到 10 范围内的整数数据,添加到列表
"""
# 使用到 python 的内置模块
import random # 先搭导入在使用
print(random.randint(1, 10)) # 随机从1到10取一个整数,左右都是闭区间
list1 = []
for i in range(10): # 0123456789 随机取10次
list1.append(random.randint(1, 10))
print(list1)
案例 - 座位随机
'''
有N个人参加会议,现在需要安排座位
请用 python 实现将N个人安排座位
'''
# 员工
name = """
邓永明 廖徳超 张勇 杨久林 戴贵富 秦代坤 李元东 田显余
"""
# 办公室名字
site_list = ['1号办公室1位置', '1号办公室2位置', '1号办公室3位置',
'2号办公室1位置', '2号办公室2位置', '2号办公室3位置',
'3号办公室1位置', '3号办公室2位置'
]
# 方法一
# 将字符串分割成一个列表
name_list = name.split()
print(name_list)
result = []
for i in range(len(name_list)): # 取到 01234567
result.append([site_list[i], name_list[i]])
print(result)
案例 - 深浅拷贝
"""
运行代码之后,请找出下面代码错误并且修正
提示:深浅拷贝,数据不重复
"""
import copy
data = {
'cate': '童书馆',
'sub_cate': None
}
sub_cate = ['科普百科', '儿童文学', '幼儿启蒙', '动漫卡通', '少儿英语']
all_cate = [] # 定义一个空的列表
# 在字典进行添加的时候,由于他们引用的是同一个对象,由于字典的键是相同的
# 会把前面的内容进行覆盖
for cate in sub_cate:
data['sub_cate'] = cate # 通过字典的键赋值
print(id(data))
# all_cate.append(data) # 把字典添加到空的列表里面去
# 浅拷贝,适用于一维维度
all_cate.append(copy.copy(data))
print('浅拷贝', id(copy.copy(data)))
# 深拷贝,适用于所有维度
all_cate.append(copy.deepcopy(data))
print('深拷贝', id(copy.deepcopy(data)))
# print(all_cate)