python数据类型之列表

news2024/9/8 12:20:57

目录

1.创建列表

2.列表基础操作

常用操作

对列表元素顺序随机打乱

列表下标和切片

字符串分割为列表

列表位移

列表切片替换

3.列表内置方法

4.列表排序

简单排序

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

二维列表排序

自定义排序规则函数

5.列表排序算法

选择排序

柱状图动画展示插入排序

插入排序

柱状图动画展示插入排序

6.列表查找算法

线性查找

二分查找

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

引用(地址相同)

浅拷贝和深拷贝

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

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

用深浅拷贝处理列表参数

8.多维列表

二维列表:矩阵

三维列表


1.创建列表

用list方法创建

list1 = list()  # 创建一个空列表
list2 = list([2, 3, 4])
list3 = list(["red", "green", "blue"])
list4 = list(range(3, 6))
list5 = list("abcd")
使用更简洁的方法来创建列表
list1 = []
list2 = [2, 3, 4]
list3 = ["red", "green"]
list4 = [2, "red", 4]  # 列表中可以包含不同类型的元素
进阶创建方法:"列表构造表达式"
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.列表基础操作

常用操作

对列表元素顺序随机打乱

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”

示例代码

lst = [1, 2, 3, 4, 5]
print(lst[10])

结果报错

IndexError: list index out of range

考虑对“IndexError”异常的处理

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

字符串分割为列表

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']

列表位移

左移
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]

右移

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]

或者这样

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]

列表切片替换

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]

替换注意事项:多增少减

# 多增例子
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 个数不同时会报错
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以升序对列表中的元素排序

示例代码

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.列表排序

简单排序

# 升序
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参数按指定规则排序

# 按照元素第一个元素排序
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']

二维列表排序

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

# 二维列表
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:按照第一个元素排序,如果第一个元素相同,则按照第二个元素排序

# 定义一个比较函数,用于排序
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:如果第一个元素相同,则按照第二个元素降序排序

# 定义一个比较函数,用于排序
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小的元素将被排在第二个位置)
  • 循环到只剩一个元素
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]

柱状图动画展示插入排序

# 柱状图:选择排序动画
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()

插入排序

该算法的思路是是重复地将一个新元素插入到一个已排好序的子列表中,直到整个列表排好序
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()

柱状图动画展示插入排序

# 柱状图:插入排序动画
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.列表查找算法

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

线性查找

原理是暴力查找,依顺序将要查找的那个元素与列表的每一个元素进行比较
# -*- 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为底数)成对数关系。

# -*- 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 与原列表相同

# -*- 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]

浅拷贝和深拷贝

  • 浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
  • 深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
浅拷贝:只能保证第一层不会被改变
# -*- 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]
深拷贝:保证内层所有层不会被改变
# -*- 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]]

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

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

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

# -*- 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 都指向同一个列表对象
"""

用深浅拷贝处理列表参数

# -*- 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.多维列表

二维列表:矩阵

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

将矩阵数据转化为列表
# -*- 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)
二维列表遍历
# -*- 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()

二维列表求和

# -*- 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)
随意打乱一个矩阵
# -*- 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 方法可以对一个二维列表排序
# -*- 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],从第一个元素依次比较,直到分出大小。

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

矩阵转置
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1703105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4-主窗口

4-主窗口 1、简介2 菜单栏、工具栏、状态栏2.1 菜单栏2.2 QAction2.3 工具栏2.4 状态栏 3 混合方式UI设计 1、简介 QMainWindow是一个为用户提供主窗口程序的类&#xff0c;包含一个菜单栏、多个工具栏、多个停靠控件、一个状态栏以及一个中心控件&#xff0c;是许多应用程序&…

宝塔部署前后端分离项目手册

文章目录 安装宝塔安装环境开始部署1. 前端Vue项目1.先本地启动前端项目&#xff08;记住端口号&#xff09;2.打包前端项目3.上传前端项目4.创建PHP站点5.安全里开放端口号6.测试前端 2. 后端boot项目1. 先在本地跑起来2.修改数据库的配置信息3. 项目打包4. nohup启动项目4.1 …

2024年必看!会声会影神器升级,让你的视频制作技能直线上升

在数字媒体内容呈现爆炸式增长的今天&#xff0c;无论是个人还是企业&#xff0c;都开始重视视频制作与编辑的质量。一款优秀的视频编辑软件&#xff0c;不仅需要具备强大的功能&#xff0c;更需要提供直观、高效的用户体验。在这样的背景下&#xff0c;会声会影2024应运而生&a…

《开发问题解决》Window下7z解压:cannot create symbolic link : 客户端没有所需的特权

问题描述&#xff1a; 今天使用7z来解压东西的是突然出现这个问题。 问题解决&#xff1a; download直接下载到c盘中&#xff0c;由于所在文件夹有权限限制。无法进行正常解压。 7.zip解压时使用管理员权限进行解压&#xff0c;解压时使用管理员权限。即如图 使用管理员权限重…

基于飞书机器人跨账号消息提醒

事情的起因是飞书中不同的账号不能同时登录&#xff0c;虽然可以在飞书的账号切换页面看到其他账号下是否有消息提醒&#xff08;小红点&#xff09;&#xff0c;但是无法实现提醒功能&#xff0c;很不优雅&#xff0c;因此本文尝试提出一种新的方式实现不同账号之间的提醒功能…

基于Go实现的分布式主键系统

基于Go实现的分布式主键系统 摘要 随着互联网的发展&#xff0c;微服务得到了快速的发展&#xff0c;在微服务架构下&#xff0c;分布式主键开始变得越来越重要。目前分布式主键的实现方式颇多&#xff0c;有基于数据库自增的、基于UUID的、基于Redis自增的、基于数据库号段的…

时空AI软件:地理信息与遥感领域的智慧引擎

在地理信息与遥感技术的广阔疆域&#xff0c;时空AI软件如同一颗璀璨新星&#xff0c;将时空信息与智能深度融合&#xff0c;驱动着地理信息分析、决策支持、环境监测、城市规划等领域的深刻变革。本文将深入剖析其技术核心、应用实例、未来趋势&#xff0c;探索时空AI软件如何…

OrangePi Kunpeng Pro 开发板测评及Python开发实测

一、背景 首先感谢 创新乐知通过CSDN 邀请本人&#xff0c;参与这次 评测活动。这块开发板是香橙派联合华为精心打造&#xff0c;具有超强算力的鲲鹏开发板。本人使用最多的还是树莓派系列的板子&#xff0c;国产板子特别是华为为核心的板子还是头一次使用&#xff0c;特别感兴…

使用 Spring Cloud Alibaba AI 构建 RAG 应用

作者&#xff1a;姬世文 背景介绍 RAG&#xff08;Retrieval Augmented Generation&#xff09; 检索增强生成&#xff08;RAG&#xff09;是一种用于将数据与人工智能模型集成的技术。在 RAG 工作流程中&#xff0c;第一步将文档数据加载到矢量数据库&#xff08;例如 Redi…

【Day8:JAVA字符串的学习】

目录 1、常用API2、String类2.1 String类的特点2.2 String类的常见构造方法2.3 String类的常见面试题&#xff1a;2.3.1 面试题一&#xff1a;2.3.2 面试题二&#xff1a;2.3.3 面试题三&#xff1a;2.3.4 面试题四&#xff1a; 2.4 String类字符串用于比较的方法2.5 String类字…

万博智云×华为云 | HyperBDR云容灾上架,开启联营联运新篇章

日前&#xff0c;万博智云HyperBDR云容灾正式入驻华为云云商店&#xff0c;成为华为云基础软件领域联营联运合作伙伴。通过联营联运&#xff0c;双方将进一步加深在产品、解决方案、渠道拓展等多方面的强强联合&#xff0c;为企业提供更加安全、高效的数据保护解决方案&#xf…

halcon 传统缺陷检测

一、电路检测 算子解释 dyn_threshold *dyn_threshold 利用局部阈值分割图像*OrigImage (input_object)&#xff1a;原始图像*ThresholdImage (input_object)&#xff1a;处理后图像&#xff08;一般采用滤波处理&#xff09;*RegionDynThresh (output_object)&#xff1…

GpuMall智算云:QwenLM/Qwen1.5/Qwen1.5-7B-Chat

Qwen 是阿里巴巴集团 Qwen 团队的大型语言模型和大型多模态模型系列&#xff0c;现在大型语言模型已经升级到 Qwen1.5 版本。 GpuMall智算云 | 省钱、好用、弹性。租GPU就上GpuMall,面向AI开发者的GPU云平台 无论是语言模型还是多模态模型&#xff0c;都在大规模的多语言和多模…

新楚文化知网收录文学艺术类期刊投稿

《新楚文化》是由国家新闻出版总署批准&#xff0c;湖北省文学艺术界联合会主管&#xff0c;湖北今古传奇传媒集团有限公司主办的正规期刊。主要刊登文化、文学、艺术类稿件&#xff1b;包括传统文化、非遗、历史文化、地方文化、中外友好文化交流、文学作品研究、艺术研究等方…

20240527每日前端-------聊聊前端input file 文件框“取消”按钮事件

文件选择窗口 正常我们使用input type"file"属性上传文件&#xff0c;会唤起系统的文件选择器如下&#xff1a; 打开按钮 可以通过change事件监听&#xff1a; // 增加的部分&#xff1a;创建 loading 实例变量 let loadingInstance;let box document.createEl…

流量分析入门

什么是流量分析 通过捕捉网络中流动的数据包&#xff0c;查看里面的数据和协议&#xff0c;流量分析和各种数据的统计来发现网络运行中的问题&#xff0c;在ctf中一般是一个包含流量数据的 PCAP 文件。 [陇剑杯 2021]签到 1.题目问我们正在进行的事什么协议的攻击 2.打开wire…

Spring Boot开发中常用注解总结【建议收藏】

Spring Boot 是一款非常流行的 Java 框架&#xff0c;其注解用法复杂而丰富。 在介绍 Spring Boot 的注解之前&#xff0c;我们需要先了解 Spring框架中的 AOP&#xff08;面向切面编程&#xff09;概念。 Spring 的 AOP 可以帮助开发者实现一些非业务功能的代码&#xff0c;如…

Vue3:封装Table 表格组件

组件官网 elementPlus : 点击跳转 封装组件 创建新的组件文件: Table.vue <!-- PropTableS &#xff1a; 父组件传递过来的数据 (对象)PropTableS.tables : 父组件传递的对象中 存放表格每行显示的数据PropTableS.keyS &#xff1a; 父组件传递过来的对象&#xff0c;里…

第十四 Elasticsearch介绍和安装

docker-compose安装 kibana: image: docker.elastic.co/kibana/kibana:7.5.1 container_name: kibana ports: - "5601:5601" environment: ELASTICSEARCH_HOSTS: http://elasticsearch:9200 depends_on: - elasticsearch…

所有平台均可发布,矩阵操作+工具+素材,自动混剪8090后怀旧视频

“怀旧”这个词对于80、90后来说&#xff0c;总能勾起一阵阵心中的涟漪。无论是那些留存在记忆深处的动画经典&#xff0c;还是代代相传的游戏主题曲&#xff0c;亦或是那个时代特有的玩具&#xff0c;都构成了他们共同的美好回忆。就像乘坐一艘穿梭机&#xff0c;怀旧视频能够…