python数据类型之列表(一)

主要讲解列表的特点、内置方法、切片等,纯手码
 
一、特点:
①是可变类型,可以直接修改原列表
②是有序集合
 
二、列表常用操作
1、insert()
lst = ['张三', '王五']

# 指定索引前插入,lst.insert()没有返回值
lst.insert(1, '李四') 
print(lst) # >>>['张三', '李四', '王五']
2、append() 
lst = ['张三', '王五']

# 末尾插入,lst.append()没有返回值
lst.append('李四')  
print(lst)  # >>>['张三', '王五', '李四']
3、extend()
# 末尾插入,无返回值,功能比append强大很多。类似列表拼接,但是跟拼接的区别是extend修改了原列表;拼接生成的是新列表,效率较低
lst1 = ['a', 'b', 'c']
lst1.extend('dd')  # 分解字符串插入
lst1.extend(['dd'])  # 完整字符串插入
lst1.extend(('ef'))  # 分解元组插入
lst1.extend([('ef')])  # 完整元组插入
print(lst1)  # >>>['a', 'b', 'c', 'd', 'd', 'dd', 'e', 'f', 'ef']
4、pop()
# 默认删除末尾元素,也可指定索引删除。有返回值,返回被删除元素
lst1 = ['a', 'b', 'c', 'd']
a = lst1.pop()
b = lst1.pop(0)
print('删除后:%s,删除末尾:%s,删除指定:%s' % (lst1, a, b))
# >>>删除后: ['b', 'c'] 删除末尾: d 删除指定: a
5、remove()
# 删除被指定的第一个元素。有返回值
lst1 = ['a', 'b', 'c', 'd', 'c']
lst1.remove('c') 
print(lst1)  # >>>['a', 'b', 'd', 'c']
6、del
# 指定索引删除。无返回值
lst1 = ['a', 'b', 'c', 'd', 'c']
del lst1[0]
print('删除后:', lst1)  # >>>删除后: ['b', 'c', 'd', 'c']
7、sort()
# sort(key=None,reverse=False) 排序,默认升序,对原列表进行了修改
# 默认用法,升序 
lst1 = [888, 12, 999] 
lst1.sort()  # reverse默认False
print(lst1) 

# 降序 
lst1 = [888, 12, 999] 
lst1.sort(reverse=True) 
print(lst1) 

# 使用key参数 
lst1 = [[888, 12], [12, 55], [999, 63], [13, 31]] 
lst1.sort(key=lambda x: x[1])  # 将每个列表中的第二个元素给key再排序,拿到的结果是:12,55,63,31 
print(lst1) 
# >>>[[888, 12], [13, 31], [12, 55], [999, 63]]
8、sorted()
# sorted(iterable, cmp=None, key=None,reverse=False) 对所有可迭代的对象进行排序,返回排好序的列表,不会对原列表进行修改
# 返回排好序的新列表
lst1 = [888, 12, 999]
for i in sorted(lst1):
    print(i)

# 使用key参数
lst1 = [[888, 31], [12, 23], [999, 41]]
new_lst = sorted(lst1, key=lambda x: x[1])
print('原列表:%s\n新列表:%s' % (lst1, new_lst))
# >>> 原列表:[[888, 31], [12, 23], [999, 41]]
# >>> 新列表:[[12, 23], [888, 31], [999, 41]]

9、reserve()

# 翻转列表。无返回值
lst = ['a', 'b', 'c']
lst.reverse()
print(lst)  # >>>['c', 'b', 'a']
10、reversed()
# reserved(seq) 返回一个反向的迭代器,seq为要转换的序列,可为list,string,tuple,range
# list
lst1 = ['a', 'b', 'c']
a = list(reversed(lst1))  # 将迭代器用列表包起来
print(a)  # >>>['c', 'b', 'a']

# string
str1 = 'qwe'
a = list(reversed(str1))  # 将迭代器用列表包起来
print(a)  # >>>['e', 'w', 'q']

# tuple
tup1 = ([1, 2], [3, 4])
a = list(reversed(tup1))  # 将迭代器用列表包起来
print(a)  # >>>[[3, 4], [1, 2]]

# range
ran1 = range(1, 4)
a = list(reversed(ran1))  # 将迭代器用列表包起来 print(a)
print(a)  # >>>[3, 2, 1]
11、clear()
# 清空列表所有元素,无返回值
lst1 = ['a', 'b', 'c']
lst1.clear()
print(lst1)  # >>>[]
12、index()
# 获取指定元素的索引,有返回值,返回索引
lst1 = ['a', 'b', 'c']
a = lst1.index('a')
print(a)  # >>>0
13、count()
# 获取指定元素出现的次数,有返回值,返回次数
lst1 = ['a', 'b', 'c']
a = lst1.count('a')
print(a)  # >>>1
14、copy()与deepcopy() -浅拷贝与深拷贝
14.1 浅拷贝
import copy

# 浅拷贝1(赋值引用)
lst1 = [1, 2, 3]
lst2 = lst1  # 指向同一内存地址
if lst1 is lst2:  # True
    lst2.append(4)
    print("浅拷贝1(赋值引用):", lst1)  # >>>[1, 2, 3, 4]
    print("浅拷贝1(赋值引用):", lst2)  # >>>[1, 2, 3, 4]

# 浅拷贝2(copy)
# 注意点1、copy.copy对于拷贝的整个对象,两者指向不同内存,两者独立  --深拷贝
lst3 = [0, [123]]
lst4 = copy.copy(lst3)
if not (lst3 is lst4):  # not False
    print("copy的整个对象,两者内存不一样")
lst4.append([456])
print("copy之父对象相互独立:", lst3)  # >>>[0, [123]]
print("copy之父对象相互对立:", lst4)  # >>>[0, [123], [456]]

# 注意点2、copy.copy对于拷贝的对象中如果存在不可变类型元素(数字、字符串、元组),拷贝前后的两个不可变元素指向相同内存,但是两者仍然独立  --深拷贝
lst5 = [0, [123]]
lst6 = copy.copy(lst3)
if lst5[0] is lst6[0]:  # True
    print("拷贝前后两个不可变类型元素的内存一样") 
lst6[0] = 1  # 0是不可变类型
print("copy之父对象的可变子对象相互独立:", lst5)  # >>>[0, [123]]
print("copy之父对象的可变子对象相互独立:", lst6)  # >>>[1, [123], [456]]

# 注意点3、copy.copy对于拷贝的对象中如果存在可变类型(列表、字典、集合),拷贝前后的两个可变类型的元素指向相同内存,两者元素的值互相影响  --浅拷贝
lst7 = [0, [123]]
lst8 = copy.copy(lst7)
lst8[1].append(4)  # [123]是可变类型,修改lst8后,lst7也会变化
print("copy之父对象的不可变子对象被浅拷贝:", lst7)  # >>>[1, [123, 4]]
print("copy之父对象的不可变子对象被浅拷贝:", lst8)  # >>>[1, [123, 4]]

14.2 深拷贝

import copy

# 深拷贝(赋值引用)
lst1 = ['a', 'b', 'c']
lst2 = lst1[:]  # 申请新的内存地址,然后复制
if not (lst1 is lst2):  # 判断内存地址是否不一样,>>>True
    lst2.append('d')  # 修改lst2,lst1不会被修改
    print(lst1)  # ['a', 'b', 'c']
    print(lst2)  # ['a', 'b', 'c', 'd']

# 深拷贝(deepcopy)
lst3 = ['a', 'b', ['ab']]
lst4 = copy.deepcopy(lst3)
if not (lst3 is lst4):  # not False 判断整个对象的内存是否不一样
    if not (lst3[0] is lst4[0]):  # not False 判断整个对象中的的不可变类型的元素的内存是否不一样
        if not (lst3[2] is lst4[2]):  # not False 判断整个对象中的可变类型的元素的内存是否不一样
            print("深拷贝对于对象中的元素都会重新申请新的内存,拷贝前后的对象没有任何关系")

14.3 copy和deepcopy的原理及应用

 A、copy.copy()
①copy整个对象的时候:申请了一个新的内存地址,所以对copy后的整个对象进行增删元素的操作就不会影响copy前的对象(这个特性有点类似深拷贝)
②copy整个对象中的元素的时候:会区分元素类型是否是可变,如果是不可变的元素,copy的时候不申请新内存,和被copy的元素对象指向同一内存,但是修改copy后的元素,不会影响copy前的元素(这个特性有点类似深拷贝)
③copy整个对象中的元素的时候:会区分元素类型是否是可变,如果是可变的元素,copy的时候不申请新内存,和被copy的元素对象指向同一内存,但是修改copy后的元素,copy前的元素也会被修改
 
B、copy.deepcopy()
不管是整个对象,还是整个对象中的元素,deepcopy的时候都会申请新的内存地址,deepcopy前后的对象互不干涉
 
C、应用
import copy
lst1 = [1, 2, 3]
num_lst = [4, 5]
lst1.append(num_lst)  # 浅拷贝,赋值引用,相当于将num_lst直接赋值给一个对象后再插入到lst1
num_lst.clear()  # 此时清空num_lst
print(lst1)  # 发现lst1中的元素也被修改  >>>[1, 2, 3, []]

lst1 = [1, 2, 3]
num_lst = [4, 5]
lst1.append(copy.deepcopy(num_lst))  # 申请新的内存,将新的对象插入lst1
num_lst.clear()  # 此时清空num_lst
print(lst1)  # 发现lst1中的元素不会被修改  >>>[1, 2, 3, [4, 5]]

 

 
posted @ 2022-10-13 16:21  杰个就斯爱情o  阅读(103)  评论(0)    收藏  举报