列表相关

1.两个列表相加会得到一个新的列表

a = [1, 2, 3, 4]
b = [5, 6]
c = a + b
print(c)    #c=[1, 2, 3, 4, 5, 6] 
a[0] = 100
print(c)    #c = [1, 2, 3, 4, 5, 6] 因为两个列表a、b相加,会等到一个新的列表,然后将c指向这个新的列表。所以a列表的改变不会影响c列表

 2.对列表来说,a+=b和a=a+b不同

b = a = [1, 2]
a += [3]    #a += [3]是在a列表里追加3
print(a, b)  #[1, 2, 3] [1, 2, 3]
a = a + [4, 5]  #a = a + [4, 5] 是生成了一个新的列表[1, 2, 3, 4, 5],然后让a指向这个新的列表
print(a)    #[1, 2, 3, 4, 5]
print(b)    #[1, 2, 3]

 3.理解列表例题

a = [[0]]*2 + [[0]]*2
a[0][0] = 5
print(a)

A  [5, 0, 0, 0]
B  [5, 5, 5, 5]
C  [[5], [5], [0], [0]]
D  [[5], [5], [5], [5]]

 分析:

第一条语句:a = [[0]]*2 + [[0]]*2 是先申请了一个列表[0],再执行[[0]]*2操作,得到列表[[0], [0]];接下来在内存中申请一个列表[0](这个列表[0]和前面的列表[0],不是同一个列表,因为列表是可变对象),得到列表[[0], [0]];最后两个[[0], [0]]相加,得到[[0], [0], [0], [0]]

第二条语句:a[0][0] = 5,将第一个列表[[0]]中的0改为5 ,故第一个列表执行*2,变为[[5],[5]]。最后选C

 最终效果为:

4.列表的排序

列表排序有sort()和sorted()两个方法,sort()方法会改变列表本身,sorted()方法会生成一个新的列表,不会改变列表本身

 

# 列表的排序

a = [5, 7, 6, 3, 4, 1, 2]
a.sort()            # sort()方法,会改变列表a
print(a)
a = [5, 7, 6, 3, 4, 1, 2]
b = sorted(a)       # sorted()方法不会改变列表a,会返回一个新的列表
print(a)
a = [25, 7, 16, 33, 4, 1, 2]
a.sort(reverse=True)
print(a)
a = [25, 7, 16, 33, 4, 1, 2]
b = sorted(a, reverse=True)
print(a)
print(b)

 5.列表的自定义排序

# 自定义排序


def mykey(x):
    return x % 10


a = [25, 7, 16, 33, 4, 1, 2]
a.sort(key=mykey)
print(a)                          # a =  [1, 2, 33, 4, 25, 16, 7]
b = sorted('This is a test string from Andrew'.split(), key=str.lower)
print(b)
students = [
    ('John', 'A', 15),
    ('Mike', 'C', 19),
    ('Mike', 'B', 12),
    ('Mike', 'C', 18),
    ('Bom', 'D', 10),
]
students.sort(key=lambda x: x[2])  # lambda表达式,实际上就是一个函数,x为输入,x[2]为输出
print(students)             
students = [
    ('John', 'A', 15),
    ('Mike', 'C', 19),
    ('Mike', 'B', 12),
    ('Mike', 'C', 18),
    ('Bom', 'D', 10),
]
students.sort(key=lambda x: x[0])
print(students)            #python排序算法为稳定排序算法(以前在前面的依然在前面,在后面的依然在后面)

6.元组不能修改,所以不能用sort()排序,但可以用sorted()排序,排序之后得到的是列表

def f(x):
    return (-x[2], x[1], x[0])


students = (
    ('John', 'A', 15),
    ('Mike', 'C', 19),
    ('Wang', 'B', 12),
    ('Mike', 'B', 12),
    ('Mike', 'C', 18),
    ('Mike', 'C', 18),
    ('Bom', 'D', 10),
)                               # students是元组
print(sorted(students, key=f))  # 排序后是列表

 7.列表的函数

# 列表函数

a, b = [1, 2, 3], [5, 6]
a.append(b)
print(a)
b.insert(1, 100)
print(a)
a.extend(b)             # extend()相当于+=
print(a)
a.insert(1, 'k')
a.insert(3, 'k')
print(a)
a.remove('k')
print(a)
a.reverse()
print(a)
print(a.index('k'))
try:
    print(a.index('m'))
except Exception as e:
    print(e)

8.列表的映射和过滤

map(function, sequence),可用于将一个序列(列表、元组、集合。。。)映射到另一个序列

返回一个延时求值对象,可以转换成list、tuple、set

# 列表的映射返回一个延时求值对象,并把返回结果收集起来
def f(x):
    print(x, end="")
    return x*x


a = map(f, [1, 2, 3])
print(list(a))          # 123[1, 4, 9]
print(tuple(a))         # ()
a = list(map(lambda x: 2*x, [2, 3, 4]))
print(a)                # [4, 6, 8]

map可以用于输入:

a, b = map(int, input().split())  # 此处tuple省略

filter(function, sequence),抽取数列中令function(x)为True的元素x

返回一个延时求值对象,可以转换成list、tuple、set

# 列表过滤
def f(x):
    if x%2 == 0:
        return x
    # return x%2 == 0


lst = tuple(filter(f, [1, 2, 3, 4, 5]))
print(lst)

 9. 列表生成式(列表推倒式)

print([x*x for x in range(1, 11)])
print([x*x for x in range(1, 11) if x%2==0])
print([m+n for m in 'ABC' for n in 'XYZ'])      # ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
l = [[m+n for m in 'ABC'] for n in 'XYZ']      # [['AX', 'BX', 'CX'], ['AY', 'BY', 'CY'], ['AZ', 'BZ', 'CZ']]
print(l)

L = ['Hello', 'World', 18, 'Apple', None]
l = [s.lower() for s in L if isinstance(s, str) ]
print(l)
l = [s for s in L if isinstance(s, int) ]
print(l)

# 元组列表生成式,必须有tuple,不然返回的是地址
print(tuple( x*x for x in range(1,11)))

 10.二维列表

二维列表可以看成矩阵,a[i][j]就是第i行第j列的元素

# 错误生成二维列表的方法
a = [0, 0, 0]
b = [a] * 3
print(b)      # b = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
b[0][1] = 1
a[2] = 100
print(b)      # b = [[0, 1, 100], [0, 1, 100], [0, 1, 100]] 修改b[0][1],b[1][1]和b[2][1]也改变了。因为b中的每个列表和a都指向同一地址
# 定义二维列表
# 二维列表本质上还是列表,列表中的列表指向内存中不同的地方

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix)
print(matrix[1][2], matrix[2][2])
matrix[1][1] = 100
print(matrix)

用列表推导式定义二维列表

# 列表推导式初始化矩阵
matrix = [[0 for i in range(3)] for i in range(3)]
print(matrix)
matrix = [[i*3+j for j in range(3)] for i in range(3)]
print(matrix)

生成一个三行四列的二维列表,并初始化

# 生成一个3行4列的矩阵,所有元素都是0
lst = []
for i in range(3):
    lst.append([0]*4)
lst[0][0] = lst[2][3] = 100
for i in range(3):
    for j in range(4):
        print(lst[i][j], end=" ")
    print("")

定义二维元组

# 二维元组
matrix = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
print(matrix)
matrix = tuple(tuple(0 for i in range(3)) for i in range(3))
print(matrix)

 11.列表的拷贝

浅拷贝:拷贝指针(地址)

深拷贝:实现值的拷贝(两个列表完全分割,修改一个不会影响另一个)

# 列表的浅拷贝

a = [1, 2, 3, 4]
b = a[:]             # b是a的拷贝,b和a不是同一个对象,指向不同的东西。 b=a是指针的拷贝,b和a指向同一内存地址
b[0] = 5
print(a)            # a = [1, 2, 3, 4]   对b的修改不会影响a
b += [10]
print(a)            # a = [1, 2, 3, 4]   对b的修改不会影响a

列表浅拷贝存在的问题:当列表中有列表时,做不到完全分割

# 列表浅拷贝的问题
# 列表的浅拷贝只是拷贝的指针(地址)

a = [1, [2]]
b = a[:]
b.append(4)
print(b)            # b = [1, [2], 4]
a[1].append(3)
print(a)            # a = [1, [2,3]]    此处对列表a进行了修改
print(b)            # b = [1, [2,3], 4]     影响了列表b,因为b[2]和a[2]指向的是同一内存地址

列表的深拷贝

# 列表的深拷贝
import copy
a = [1, [2]]
b = copy.deepcopy(a)
b.append(4)
print(b)            # b = [1, [2], 4]
a[1].append(3)
print(a)            # a = [1, [2, 3]]   此处对a进行了修改
print(b)            # b = [1, [2], 4]   a的修改未对b产生影响

 

posted @ 2021-03-19 23:39  李成敏  阅读(32)  评论(0编辑  收藏  举报