python数据类型之列表

目录

1.创建列表

2.列表基础操作

常用操作

对列表元素顺序随机打乱

列表下标和切片

字符串分割为列表

列表位移

列表切片替换

3.列表内置方法

4.列表排序

简单排序

使用key参数按指定规则排序

二维列表排序

自定义排序规则函数

5.列表排序算法

选择排序

柱状图动画展示插入排序

插入排序

柱状图动画展示插入排序

6.列表查找算法

线性查找

二分查找

7.引用、浅拷贝和深拷贝

引用(地址相同)

浅拷贝和深拷贝

列表作为函数参数注意事项

注意列表作为实参传递给函数形参是引用

用深浅拷贝处理列表参数

8.多维列表

二维列表:矩阵

三维列表


1.创建列表

用list方法创建

python 复制代码
list1 = list()  # 创建一个空列表
list2 = list([2, 3, 4])
list3 = list(["red", "green", "blue"])
list4 = list(range(3, 6))
list5 = list("abcd")

使用更简洁的方法来创建列表

python 复制代码
list1 = []
list2 = [2, 3, 4]
list3 = ["red", "green"]
list4 = [2, "red", 4]  # 列表中可以包含不同类型的元素

进阶创建方法:"列表构造表达式"

python 复制代码
list5 = [x for x in range(5)]
list6 = list3 = [x**2 for x in list2 if x < 3]
list6 = [[x, x+1, x**2] for x in list2 if x % 2 == 1]
mylist = [[x, y] for x in range(0, 10, 2) for y in range(1, 10, 2)]  # 生成矩阵
mylist = [[2*x, y+1] 
          for x in range(0, 10, 2) 
          for y in range(1, 10, 2) 
          if x % 2 == 0
          and y % 2 != 0] 

2.列表基础操作

常用操作

对列表元素顺序随机打乱

python 复制代码
import random

list1 = [1, 2, 3, 4, 5]
random.shuffle(list1)
print(list1)  # [4, 5, 2, 1, 3]

列表下标和切片

和字符串类似

myList[-1] = myList[-1 + len(myList)]

注意避免因 < 和 <= 的使用不当造成列表的"越级访问",就是超过列表长度的访问,它会出现一个运行时的"IndexError"

示例代码

python 复制代码
lst = [1, 2, 3, 4, 5]
print(lst[10])

结果报错

bash 复制代码
IndexError: list index out of range

考虑对"IndexError"异常的处理

python 复制代码
lst = [1, 2, 3, 4, 5]
try:
    print(lst[10])
except IndexError:
    print("索引越界")

字符串分割为列表

python 复制代码
string = "name xxx ttt" 
list1 = string.split()  # 默认用空格分隔
print(list1)  # ['name', 'xxx', 'ttt']

items = "09/17/2020".split("/")  # 用/分割
print(items)  # ['09', '17', '2020']

s1 = "welcome" 
list2 = s1.split("o")  # 用o分割
print(list2)  # ['welc', 'me']

列表位移

左移

python 复制代码
def left_shift(lst):
    temp = lst[0]
    for i in range(1, len(lst), 1):
        lst[i - 1] = lst[i]
    lst[len(lst) - 1] = temp


data = [1, 2, 3, 4]
left_shift(data)
print(data)   # [2, 3, 4, 1]

右移

python 复制代码
def right_shift(lst):
    temp = lst[len(lst) - 1]
    for i in range(len(lst) - 1, 0, -1):
        lst[i] = lst[i - 1]
    lst[0] = temp


data = [1, 2, 3, 4]
right_shift(data)
print(data)   # [4, 1, 2, 3]

或者这样

python 复制代码
data = [1, 2, 3, 4]

# 左移
num = 1
lst = data[num:] + data[:num]
print(lst)   # [2, 3, 4, 1]

# 右移
num = 1
lst = data[-num:] + data[:-num]
print(lst)   # [4, 1, 2, 3]

列表切片替换

python 复制代码
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst[0:2] = [0, 0]
print(lst)  # [0, 0, 3, 4, 5, 6, 7, 8, 9]

替换注意事项:多增少减

python 复制代码
# 多增例子
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst[0:2] = [0, 0, 0, 0, 0]
print(lst)  # [0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 8, 9]

# 少减例子
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst[0:7] = [0, 0, 0]
print(lst)  # [0, 0, 0, 8, 9]

但 lst[i:j:k] = newList 个数不同时会报错

python 复制代码
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst[0:7:2] = [0, 0, 0]   # 0:7:2为0 2 4 6共4个数,[0, 0, 0]为3个数
"""
会报错
ValueError: attempt to assign sequence of size 3 to extended slice of size 4
"""

3.列表内置方法

|------------------------------------|-----------------------------------------------------------------|
| 方法 | 作用 |
| append(x: object): None | 将元素添加到列表结尾 |
| count(x: object): int | 返回元素x在列表中的出现次数 |
| extend(lst: list): None | 将lst中的所有元素追加到列表中 |
| insert(index: int, x:object): None | 将元素x插入列表中指定下标处。 注意列表第一个元素的下标是0 |
| pop(index): object | 删除给定位置处的元素并返回它。 参数index是可选的,如果没有指定它 那么list.pop()将删除列表最后一个元素并返回它 |
| remove(x: object): None | 删除列表中第一次出现的x |
| reverse(): None | 将列表中的所有元素倒序 |
| sort(): None | 以升序对列表中的元素排序 |

示例代码

python 复制代码
data = [x for x in range(5)]
print(data)  # [0, 1, 2, 3, 4]

# append方法
data.append(100)
print(data)  # [0, 1, 2, 3, 4, 100]

# count方法
data.append(100)
print(data)  # [0, 1, 2, 3, 4, 100, 100]
print(data.count(100))  # 2
print(data.count(99))   # 0

# extend方法
data.extend([10, 20, 30])
print(data)  # [0, 1, 2, 3, 4, 100, 100, 10, 20, 30]

# insert方法
data.insert(1, 9999)
print(data)  # [0, 9999, 1, 2, 3, 4, 100, 100, 10, 20, 30]
data.insert(-1, 9999)
print(data)  # [0, 9999, 1, 2, 3, 4, 100, 100, 10, 20, 9999, 30]
data.insert(100, 9999)
print(data)  # [0, 9999, 1, 2, 3, 4, 100, 100, 10, 20, 9999, 30, 9999]

# pop方法
ret = data.pop(1)
print(ret)   # 9999
print(data)  # [0, 1, 2, 3, 4, 100, 100, 10, 20, 9999, 30, 9999]
data.pop()
print(data)  # [0, 1, 2, 3, 4, 100, 100, 10, 20, 9999, 30]

# data.pop(100)  # IndexError: pop index out of range

# remove方法
data.remove(0)
print(data)  # [1, 2, 3, 4, 100, 100, 10, 20, 9999, 30]
# data.remove(666)  # ValueError: list.remove(x): x not in list

# reverse方法
data.reverse()
print(data)  # [30, 9999, 20, 10, 100, 100, 4, 3, 2, 1]

# sort方法
data.sort()
print(data)  # [1, 2, 3, 4, 10, 20, 30, 100, 100, 9999]

data = [30, 9999, 20, 10, 100, 100, 4, 3, 2, 1]
data.sort()
data.reverse()
print(data)  # [9999, 100, 100, 30, 20, 10, 4, 3, 2, 1]

4.列表排序

简单排序

python 复制代码
# 升序
data = [30, 9999, 20, 10, 100, 100, 4, 3, 2, 1]
data.sort()
print(data)  # [1, 2, 3, 4, 10, 20, 30, 100, 100, 9999]

# 降序
data = [30, 9999, 20, 10, 100, 100, 4, 3, 2, 1]
data.sort()
data.reverse()
print(data)  # [9999, 100, 100, 30, 20, 10, 4, 3, 2, 1]

使用key参数按指定规则排序

python 复制代码
# 按照元素第一个元素排序
data = ['apple', 'watermelon', 'orange', 'lemon']
data.sort(key=lambda x: x[1])  
print(data)  # ['watermelon', 'lemon', 'apple', 'orange'] 

# 按照元素长度排序
data = ['apple', 'watermelon', 'orange', 'lemon']
data.sort(key=lambda x: len(x))  
print(data)  # ['apple', 'lemon', 'orange', 'watermelon']

# 按照元素长度排序的简洁写法
data = ['apple', 'watermelon', 'orange', 'lemon']
data.sort(key=len)  
print(data)  # ['apple', 'lemon', 'orange', 'watermelon']

# 按照元素第一个元素排序,降序
data = ['apple', 'watermelon', 'orange', 'lemon']
data.sort(key=lambda x: x[1], reverse=True)  
print(data)  # ['orange', 'apple', 'lemon', 'watermelon']

二维列表排序

按照每个子列表的第一个元素升序、第二个元素降序进行排序

python 复制代码
# 二维列表
data = [
    [3, 1, 'apple'],
    [1, 2, 'orange'],
    [2, 5, 'banana'],
    [1, 3, 'grape']
]

# 按照每个子列表的第一个元素升序、第二个元素降序进行排序
sorted_list = sorted(data, key=lambda x: (x[0], -x[1]))
# data.sort(key=lambda x: (x[0], -x[1]))

# 打印排序后的结果
for item in sorted_list:
    print(item)

# [1, 3, 'grape']
# [1, 2, 'orange']
# [2, 5, 'banana']
# [3, 1, 'apple']

自定义排序规则函数

例子1:按照第一个元素排序,如果第一个元素相同,则按照第二个元素排序

python 复制代码
# 定义一个比较函数,用于排序
def custom_sort(item):
    # 按照第一个元素排序
    first_element = item[0]
    # 如果第一个元素相同,则按照第二个元素排序
    second_element = item[1]
    return first_element, second_element


# 你的二维列表
data = [
    [3, 'apple', 'a'],
    [1, 'orange', 'b'],
    [2, 'banana', 'c'],
    [1, 'grape', 'd'],
    [3, 'pear', 'e']
]

# 使用sorted函数进行排序,传递自定义的比较函数
sorted_list = sorted(data, key=custom_sort)

# 输出排序后的结果
for x in sorted_list:
    print(x)

# [1, 'grape', 'd']
# [1, 'orange', 'b']
# [2, 'banana', 'c']
# [3, 'apple', 'a']
# [3, 'pear', 'e']

例子2:如果第一个元素相同,则按照第二个元素降序排序

python 复制代码
# 定义一个比较函数,用于排序
def custom_sort(item):
    # 按照第一个元素升序排序
    first_element = item[0]
    # 按照第二个元素降序排序
    second_element = item[1]
    return first_element, -ord(second_element[0])


# 你的二维列表
data = [
    [3, 'apple'],
    [1, 'orange'],
    [2, 'banana'],
    [1, 'grape'],
    [3, 'pear']
]

# 使用sorted函数进行排序,传递自定义的比较函数
sorted_list = sorted(data, key=custom_sort)

# 输出排序后的结果
for x in sorted_list:
    print(x)
"""
[1, 'orange']
[1, 'grape']
[2, 'banana']
[3, 'pear']
[3, 'apple']
"""

5.列表排序算法

排序算法有很多
这里重点介绍两种简单、直观的排序算法:选择排序和插入排序

选择排序

  • 该算法的思路是先将第一个元素作为最小元素,然后依次将它后面所有元素与它比较,若比它小,则并将其交换(这样一来最小的元素将被排在第一个位置)

  • 然后将第二个元素作为最小元素,跟上面一样,将它后面所有元素与它比较,若比它小,则并将其交换(这样一来第2小的元素将被排在第二个位置)

  • 循环到只剩一个元素

python 复制代码
def selectionSort(lst):
    for i in range(len(lst) - 1):
        currentMin = lst[i]
        currentMinIndex = i

        for j in range(i + 1, len(lst)):
            if currentMin > lst[j]:
                currentMin = lst[j]
                currentMinIndex = j

        if currentMinIndex != i:
            lst[currentMinIndex] = lst[i]
            lst[i] = currentMin


def main():
    lst = [1, 9, 4.5, 10.6, 5.7, -4.5]
    selectionSort(lst)
    print(lst)


main()  # [-4.5, 1, 4.5, 5.7, 9, 10.6]

柱状图动画展示插入排序

python 复制代码
# 柱状图:选择排序动画
from tkinter import *
import tkinter.messagebox
import random


class StepControl:
    def __init__(self):
        self.list = [x for x in range(1, 20 + 1)]
        self.reset()
    def reset(self):
        self.i = -1
        self.done = False
        random.shuffle(self.list)
        self.drawAStep()
    def step(self):
        if self.done:
            tkinter.messagebox.showinfo("showinfo", "列表已经排好升序")
            return # 没有这个 return 的话消息框要点两次才会消失
        if self.i == -1:
            self.i += 1
        self.drawAStep()

        if self.i >= len(self.list) - 1:
            self.done = True
            tkinter.messagebox.showinfo("showinfo", "列表已经排好升序")
        else:
            currentMin = self.list[self.i]
            currentIndex = self.i

            for j in range(self.i + 1, len(self.list)):
                if self.list[j] < currentMin:
                    currentMin = self.list[j]
                    currentIndex = j

            if currentIndex != self.i:
                self.list[currentIndex] = self.list[self.i]
                self.list[self.i] = currentMin

            self.i += 1
    def drawAStep(self):
        bottomGap = 10
        canvas.delete("line")
        canvas.create_line(10, height - bottomGap, width - 10, height - bottomGap, tags = "line")
        barWidth = (width - 20) / len(self.list)

        maxCount = int(max(self.list))

        for i in range(len(self.list)):
            canvas.create_rectangle(10 + i * barWidth,
                    (height - bottomGap) * (1 - self.list[i] / (maxCount + 4)),
                    10 + (i + 1) * barWidth,
                    height - bottomGap, tags = "line"
                    )

            canvas.create_text(10 + i * barWidth + barWidth / 2,
                            (height - bottomGap) * (1 - self.list[i] / (maxCount + 4)) - 8,
                            text = str(self.list[i]), tags = "line"
                            )
        if self.i >= 0:
            canvas.create_rectangle(10 + self.i * barWidth,
                        (height - bottomGap) * (1 - self.list[self.i] / (maxCount + 4)),
                        10 + (self.i + 1) * barWidth,
                        height - bottomGap, fill = "red", tags="line"
                        )


def step():
    control.step()


def reset():
    control.reset()


window = Tk()
window.title("选择排序动画")

width = 340
height = 150

canvas = Canvas(window, width=width, height=height, )
canvas.pack()

frame = Frame(window)
frame.pack()

Button(frame, text="Step", command=step).pack(side=LEFT)
Button(frame, text="Reset", command=reset).pack(side=LEFT)

control = StepControl()
control.drawAStep()

window.mainloop()

插入排序

该算法的思路是是重复地将一个新元素插入到一个已排好序的子列表中,直到整个列表排好序

python 复制代码
def insertionSort(lst):
    for i in range(1, len(lst)):
        currentValue = lst[i]
        k = i - 1
        
        while k >= 0 and lst[k] > currentValue:
            lst[k + 1] = lst[k]
            k -= 1
            
        lst[k + 1] = currentValue


def main():
    lst = [1, 9, 4.5, 10.6, 5.7, -4.5]
    insertionSort(lst)
    print(lst)  # [-4.5, 1, 4.5, 5.7, 9, 10.6]


main()

柱状图动画展示插入排序

python 复制代码
# 柱状图:插入排序动画
from tkinter import *
import tkinter.messagebox
import random


class StepControl:
    def __init__(self, width, height, canvas):
        self.width = width
        self.height = height
        self.canvas = canvas

        self.list = [x for x in range(1, 20 + 1)]
        self.reset()

    def reset(self):
        self.i = -1
        self.done = False
        random.shuffle(self.list)
        self.drawAStep()

    def start(self):
        if self.done:
            tkinter.messagebox.showinfo("showinfo", "列表已经排好升序")
            return # 没有这个 return 的话消息框要点两次才会消失
        if self.i == -1:
            self.i += 1

        self.drawAStep()

        if self.i >= len(self.list) - 1:
            self.done = True
            tkinter.messagebox.showinfo("showinfo", "列表已经排好升序")
        else:
            self.i += 1
            currentValue = self.list[self.i]
            k = self.i - 1
            while k >= 0 and self.list[k] > currentValue:
                self.list[k + 1] = self.list[k]
                k -= 1

            self.list[k + 1] = currentValue

    def drawAStep(self):
        width = self.width
        height = self.height
        canvas = self.canvas

        bottomGap = 10
        barWidth = (width - 20) / len(self.list)

        maxCount = int(max(self.list))

        canvas.delete("line")
        canvas.create_line(10, height - bottomGap, width - 10, height - bottomGap, tags = "line")

        for i in range(len(self.list)):
            canvas.create_rectangle(10 + i * barWidth, (height - bottomGap) * (1 - self.list[i] / (maxCount + 4)),
                                    10 + (i + 1) * barWidth, (height - bottomGap),
                                    tags = "line")
            canvas.create_text(10 + i * barWidth + barWidth / 2,
                                (height - bottomGap) * (1 - self.list[i] / (maxCount + 4)) - 8,
                                text = str(self.list[i]), tags="line")
        if self.i >= 0:
            canvas.create_rectangle(10 + self.i * barWidth,
                                    (height - bottomGap) * (1-self.list[self.i]/(maxCount+4)),
                                    10 + (self.i + 1) * barWidth,
                                    height - bottomGap,
                                    fill="red", tags="line")


# 定义窗体类:来展示主界面窗口
class Window:
    def __init__(self):
        self.window = Tk()
        self.window.title("插入排序动画")
        self.window.geometry("600x400+0+0")
        self.width = 340
        self.height = 150
        self.canvas = Canvas(self.window, width= self.width, height=self.height)
        self.canvas.pack()

        #################################
        self.control = StepControl(self.width, self.height, self.canvas) # 类中创建类
        #################################

        self.frame = Frame(self.window)
        self.frame.pack()

        Button(self.frame, text="Start", command=self.start).pack(side=LEFT)
        Button(self.frame, text="Reset", command=self.reset).pack(side=LEFT)

        self.window.mainloop()

    def start(self):
        self.control.start()

    def reset(self):
        self.control.reset()


Window()

6.列表查找算法

查找最常见的两种方法是二分查找和线性查找
如果一个列表是排好序的,那么要查找列表中的某个元素,二分查找比线性查找更有效

线性查找

原理是暴力查找,依顺序将要查找的那个元素与列表的每一个元素进行比较

python 复制代码
# -*- coding: utf-8 -*-

def linear_search(lst, key):
    result = []
    for i in range(len(lst)):
        if key == lst[i]:
            result.append(i)
    return result


data = [1, 3, 4, 2, 4, -3, 6, 2]

a = linear_search(data, 4)
b = linear_search(data, -4)
c = linear_search(data, 3)

print(a)  # [2, 4]
print(b)  # []
print(c)  # [1]

二分查找

对大型列表而言,二分查找法更高效,但是它们需要列表是提前排好序的。
工作原理是,从数组的中间元素开始比较,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到该元素。二分查找的每一次比较都使搜索范围缩小一半,因此其效率较高。

二分查找的时间复杂度是O(log n),其中n是数组中的元素数量。这意味着在最坏的情况下,需要比较的次数与数组的深度(以2为底数)成对数关系。

python 复制代码
# -*- coding: utf-8 -*-

def binary_search(lst, key):
    low = 0
    high = len(lst) - 1
    while high >= low:
        mid = (low + high) // 2
        if key < lst[mid]:
            high = mid - 1
        elif key > lst[mid]:
            low = mid + 1
        else:
            return mid
    return -(low + 1)


# --(low + 1)中"-"表示查找不到这个元素,"low + 1"表示应该插入的位置,low + 1 = 1 话表示索引为 0 的位置
data = [1, 3, 4, 2, 4, -3, 6, 2]
data.sort()
print(data)  # [-3, 1, 2, 2, 3, 4, 4, 6]

i = binary_search(data, 4)
j = binary_search(data, -4)
k = binary_search(data, 3)
print(i)  # 5
print(j)  # -1
print(k)  # 4

7.引用、浅拷贝和深拷贝

引用(地址相同)

引用就是与原来变量为同一个内存地址

在python列表中,用=号复制的列表的 id 与原列表相同

python 复制代码
# -*- coding: utf-8 -*-

lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
print(id(lst1) == id(lst2))   # False 说明地址不同

lst2 = lst1
print(id(lst1) == id(lst2))   # True 现在lst2 和lst1指向同一块地址
print(lst1)  # [1, 2, 3]
print(lst2)  # [1, 2, 3]


# 现在修改lst1,然后查看lst2是否会变化
lst1[0] = 99
print(lst1)  # [99, 2, 3]
print(lst2)  # [99, 2, 3]

浅拷贝和深拷贝

  • 浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
  • 深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。

浅拷贝:只能保证第一层不会被改变

python 复制代码
# -*- coding: utf-8 -*-

lst = [1, 2, 3, 4, 5]
lst1 = lst  # 引用
lst2 = lst.copy()  # 浅拷贝:保证第一层不会被改变

print(id(lst) == id(lst1))   # True
print(id(lst) == id(lst2))   # False
print(id(lst1) == id(lst2))  # False


lst[3] = 10000
print(lst)  # [1, 2, 3, 10000, 5]
print(lst1)  # [1, 2, 3, 10000, 5]
print(lst2)  # [1, 2, 3, 4, 5]

深拷贝:保证内层所有层不会被改变

python 复制代码
# -*- coding: utf-8 -*-

import copy

lst = [[1, 2], [3, 4]]
lst1 = lst.copy()    # 浅拷贝
lst2 = copy.deepcopy(lst)  # 深拷贝

print(id(lst), id(lst1), id(lst2))  
# 2096876497224 2096876497160 2096876497096

lst[0][0] = 100
print(lst)  # [[100, 2], [3, 4]]
print(lst1)  # [[100, 2], [3, 4]]
print(lst2)  # [[1, 2], [3, 4]]

列表作为函数参数注意事项

注意列表作为实参传递给函数形参是引用

列表用=赋值是引用。列表作为形参赋值给形参后,在函数内部若对形参进行了值修改,则原实参那个列表内容会发生改变。这一点需要非常注意,避免在调用函数后原列表发生改变,出现意外错误。

python 复制代码
# -*- coding: utf-8 -*-

def m(number, numbers):
    number = 1001
    numbers[0] = 5555


def main():
    x = 1
    y = [1, 2, 3]
    m(x, y)
    print("x = ", x)
    print("y[0] = ", y[0])


main()
"""
结果
x = 1
y[0] = 5555
注意 x 未发生改变,而列表发生了改变,这是因为 y 和 numbers 都指向同一个列表对象
"""

用深浅拷贝处理列表参数

python 复制代码
# -*- coding: utf-8 -*-

import copy


def test_list(m_list):
    # 调用函数时test_list(x)就是做了m_list=x这么一个赋值操作
    m_list[0] = 99
    return m_list


def test_list2(m_list):
    temp_list = m_list.copy()   # 浅拷贝
    temp_list[0] = 99
    return temp_list


def test_list3(m_list):
    temp_list = m_list.copy()  # 浅拷贝
    print(temp_list)
    temp_list[1] = [7, 8, 9]   # 改变第一层的值
    temp_list[0][0] = 88    # 改变第二层的值
    return temp_list


def test_list4(m_list):
    temp_list = copy.deepcopy(m_list)  # 深拷贝
    print(temp_list)
    temp_list[1] = [7, 8, 9]   # 改变第一层的值
    temp_list[0][0] = 88    # 改变第二层的值
    return temp_list


if __name__ == "__main__":
    # 1.列表赋值是引用,与原列表是同一个对象
    x = [1, 2, 3]
    y = x
    x[0] = 100
    print(y)   # [100, 2, 3]
    print(id(x) == id(y))  # True # 地址相同说明是同一个对象
    
    # 2.函数将实参传递给形参时是赋值
    x = [1, 2, 3]
    re_list = test_list(x)
    print(re_list)  # [99, 2, 3]
    print(x)  # [99, 2, 3]
    
    # 3.用浅拷贝解决列表做参数时改变原列表值的问题
    x = [1, 2, 3]
    re_list = test_list2(x)
    print(re_list)  # [99, 2, 3]
    print(x)  # [1, 2, 3]
    
    # 4.浅拷贝的局限:只能保证第一层不会变
    x = [[1, 2, 3], [4, 5, 6]]
    re_list = test_list3(x)
    print(re_list)  # [[88, 2, 3], [7, 8, 9]]
    print(x)  # [[88, 2, 3], [4, 5, 6]]
    
    # 5.用深拷贝保证所有层都不变
    x = [[1, 2, 3], [4, 5, 6]]
    re_list = test_list4(x)
    print(re_list)  # [[88, 2, 3], [7, 8, 9]]
    print(x)  # [[1, 2, 3], [4, 5, 6]]

8.多维列表

二维列表:矩阵

二维列表是将其他列表作为它元素的列表
二维列表可以用来存储矩阵中的数据,也就是存储二维数据


将矩阵数据转化为列表

python 复制代码
# -*- coding: utf-8 -*-

from random import randint

matrix = []
number_of_rows = 3
number_of_columns = 3

for row in range(number_of_rows):
    matrix.append([])
    for column in range(number_of_columns):
        # value = eval(input("请输入矩阵第{}行第{}列的值:".format(row, column)))
        value = randint(0, 99)
        matrix[row].append(value)

print(matrix)

二维列表遍历

python 复制代码
# -*- coding: utf-8 -*-

# 可以这样
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for row in range(len(matrix)):
    for column in range(len(matrix[row])):
        print(matrix[row][column], end=" ")
    print()

# 也可以这样
for row in matrix:
    for value in row:
        print(value, end=" ")
    print()

二维列表求和

python 复制代码
# -*- coding: utf-8 -*-


# 对所有元素求和
def sum_matrix(matrix):
    total = 0
    for row in matrix:
        for value in row:
            total += value
    return total


# 按列求和
def sum_matrix_column(matrix):
    sum_column_list = []
    for column in range(len(matrix[0])):
        sum_column = 0
        for row in range(len(matrix)):
            sum_column += matrix[row][column]
        sum_column_list.append(sum_column)
    return sum_column_list


# 找出和最大的行
def max_sum_row(matrix):
    max_value = sum(matrix[0])
    max_index = 0
    for row in range(1, len(matrix)):
        if sum(matrix[row]) > max_value:
            max_value = sum(matrix[row])
            max_index = row
    return max_value, max_index


data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(sum_matrix(data))  # 45
print(sum_matrix_column(data))  # [12, 15, 18]
print(max_sum_row(data))  # (24, 2)

随意打乱一个矩阵

python 复制代码
# -*- coding: utf-8 -*-


from random import randint


def shuffle_matrix(matrix):
    for row in range(len(matrix)):
        for column in range(len(matrix[row])):
            i = randint(0, len(matrix) - 1)
            j = randint(0, len(matrix[row]) - 1)
            matrix[row][column], matrix[i][j] = matrix[i][j], matrix[row][column]


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

排序
直接使用 sort 方法可以对一个二维列表排序

python 复制代码
# -*- coding: utf-8 -*-


data = [[8, 1, 3], [6, 7, 4], [6, 3, 4], [9, 5, 2]]
data.sort()
print(data)   # [[6, 3, 4], [6, 7, 4], [8, 1, 3], [9, 5, 2]]

可以看到它像一维列表排序一样,将每个元素(列表)比较大小,比如[8, 1, 3]和[6, 7, 4],从第一个元素依次比较,直到分出大小。

但是我们有时想按指定规则排序,参考前面的列表排序。
矩阵转置

python 复制代码
grid = [
    ['.', '.', '.', '.', '.', '.'],
    ['.', 'O', 'O', '.', '.', '.'],
    ['O', 'O', 'O', 'O', '.', '.'],
    ['O', 'O', 'O', 'O', 'O', '.'],
    ['.', 'O', 'O', 'O', 'O', 'O'],
    ['O', 'O', 'O', 'O', 'O', '.'],
    ['O', 'O', 'O', 'O', '.', '.'],
    ['.', 'O', 'O', '.', '.', '.'],
    ['.', '.', '.', '.', '.', '.']
]


def transpose(matrix):
    new_matrix = [[0]*len(matrix) for i in range(len(matrix[0]))]
    # print(new_matrix)
    for column in range(len(matrix[0])):
        for row in range(len(matrix)):
            print(matrix[row][column], end="")
            new_matrix[column][row] = matrix[row][column]
        print()

    return new_matrix


new_grid = transpose(grid)
print("----------------------------")
for item in new_grid:
    print(item)

"""
..OO.OO..
.OOOOOOO.
.OOOOOOO.
..OOOOO..
...OOO...
....O....
----------------------------
['.', '.', 'O', 'O', '.', 'O', 'O', '.', '.']
['.', 'O', 'O', 'O', 'O', 'O', 'O', 'O', '.']
['.', 'O', 'O', 'O', 'O', 'O', 'O', 'O', '.']
['.', '.', 'O', 'O', 'O', 'O', 'O', '.', '.']
['.', '.', '.', 'O', 'O', 'O', '.', '.', '.']
['.', '.', '.', '.', 'O', '.', '.', '.', '.']
"""

三维列表

二维列表是将一维列表作为元素的列表
三维列表是将二维列表作为元素的列表
以此类推


end

相关推荐
waterHBO1 小时前
python 爬虫 selenium 笔记
爬虫·python·selenium
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
AIAdvocate4 小时前
Pandas_数据结构详解
数据结构·python·pandas
小言从不摸鱼4 小时前
【AI大模型】ChatGPT模型原理介绍(下)
人工智能·python·深度学习·机器学习·自然语言处理·chatgpt
FreakStudio6 小时前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
python·嵌入式·面向对象·电子diy
redcocal7 小时前
地平线秋招
python·嵌入式硬件·算法·fpga开发·求职招聘
artificiali8 小时前
Anaconda配置pytorch的基本操作
人工智能·pytorch·python
RaidenQ8 小时前
2024.9.13 Python与图像处理新国大EE5731课程大作业,索贝尔算子计算边缘,高斯核模糊边缘,Haar小波计算边缘
图像处理·python·算法·课程设计
花生了什么树~.8 小时前
python基础知识(六)--字典遍历、公共运算符、公共方法、函数、变量分类、参数分类、拆包、引用
开发语言·python
Trouvaille ~9 小时前
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧
图像处理·python·机器学习·numpy·信号处理·时间序列分析·科学计算