python数据类型之列表

目录

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MiniMax Golang2轮面试,期望薪资25K

一面 1、自我介绍 2、简单介绍一下你们成立了这个finance的财务中台之后&#xff0c;整体的服务架构是怎么样的吗&#xff1f; 3、就你提到的预算池项目&#xff0c;展开说说背景&#xff0c;以及解决了怎么样的问题&#xff1f; 4、为什么采用针对T-1订单的异步计算方案&a…

java语言概述和代码的编译

文章目录 前言 一、机器语言 二、汇编语言 三、高级语言 四、编写代码 打印字符串 求前n项和 五、问题及解决 总结 前言 计算机经过了多年的发展&#xff0c;已经诞生了很多编程语言&#xff0c;如早期的汇编语言&#xff0c;basic语言&#xff0c;现在的高级语言C语言java语言…

计算机网络——TCP 协议的三次握手 / 四次挥手

简述 TCP / UDP 协议都是传输层的协议。 UDP 是面向无连接的协议&#xff0c;就是说发送端不在乎消息数据是否传输到接收端了&#xff0c;所以会出现数据丢失的情况&#xff0c;所以可靠性也不高。 TCP 是面向连接的、可靠的、基于字节流的传输层协议。所谓面向连接的&#…

探秘死锁:原理、发生条件及解决方案

探秘死锁&#xff1a;原理、发生条件及解决方案 死锁是多线程编程中常见的一个问题&#xff0c;它会导致程序停止响应&#xff0c;进而影响系统的稳定性和性能。理解死锁的原理、发生条件以及如何预防和解决死锁是编写健壮并发程序的关键。 1. 死锁的定义 死锁是指两个或多个…

Linux--软硬链接

目录 0.文件系统 1.软硬链接 1.1见一下软硬链接 1.2软硬链接的特征 1.3软硬链接是什么&#xff0c;有什么作用&#xff08;场景&#xff09; 0.文件系统 Linux--文件系统-CSDN博客 1.软硬链接 1.1见一下软硬链接 1.这是软链接 这个命令在Unix和Linux系统中用于创建一个符号…

SQL刷题笔记day3——第二大值

1题目 我的错误代码&#xff1a; select emp_no,salary from salaries where salary (select salary from salaries group by salary order by salary limit 1,1 ) order by emp_no asc 正确代码&#xff1a; select emp_no,salary from salaries where salary (select sal…

jellyfish安装及使用(Bioinformatics工具-020)

01 背景 基因组survey以测序技术为基础&#xff0c;基于小片段文库的低深度测序&#xff0c;通过K-mer分析&#xff0c;快速获得基因组大小、杂合度、重复序列比例等基本信息&#xff0c;为制定该物种的全基因组de novo测序策略提供有效依据。 jellyfish (水母) 是一个用于快…

Cisco Nexus Leaf上线注册到APIC,并配置带外管理IP操作方法

现场2台Nexus93108交换机需要注册到APIC上&#xff0c;成为Leaf交换机。 在ACI的架构中&#xff0c;所有Leaf节点交换机要连接到SPINE交换机上&#xff0c;我们的spine交换机型号为Nexus 9364 Leaf N93108TC-EX长这样, 前面是48个万兆电口&#xff0c;后面6个端口支持40G或100…

maven打包报错:MalformedInputException: Input length = 1

maven 打包时报错&#xff1a; [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.3.1:resources (default-resources) on project ec-work-mes: filtering /Users/ecmaster/svn/ecmaster/ynmk/ynmk-mes/ec-work/ec-work-mes/src/main/resou…

Linux配置nginx代理功能

ywtool运维工具下载链接及介绍: 工具下载/介绍/安装页面 目录 一.nginx proxy功能介绍二.配置nginx proxy功能2.1 新增nginx代理配置2.1.1 反向代理(当前只举例https转https)2.1.2 负载均衡(当前只举例https转https) 2.2 修改nginx代理配置2.2.1 手动修改配置文件2.2.2 通过此脚…

利用java8 的 CompletableFuture 优化 Flink 程序,性能提升 50%

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

【数据结构】线性表习题 |顺序表 |链表 |栈和队列

&#x1f4d6;专栏文章&#xff1a;数据结构学习笔记 &#x1faaa;作者主页&#xff1a;格乐斯 前言 线性表习题 |顺序表 |链表 |栈和队列 顺序表和链表 1、 选B 1002(5-1)108* 第i个元素地址X&#xff0c;元素长度Len&#xff0c;第j个元素地址Y 公式&#xff1a;YXL…

Docker进入容器查看内容并从容器里拷贝文件到宿主机

工作中需要从docker正在运行的镜像中复制文件到宿主机&#xff0c;于是便将这个过程记录了下来。 &#xff08;1&#xff09;查看正在运行的容器 通过以下命令&#xff0c;可以查看正在运行的容器&#xff1a; docker ps &#xff08;2&#xff09;进入某个容器执行脚本 我…

备考AMC8和AMC10竞赛,吃透2000-2024年1850道真题和解析(持续)

多做真题&#xff0c;吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一&#xff0c;通过做真题&#xff0c;可以帮助孩子找到真实竞赛的感觉&#xff0c;而且更加贴近比赛的内容&#xff0c;可以通过真题查漏补缺&#xff0c;更有针对性的补齐知识的短板。 今天我们继续…

Android Audio基础——AudioFlinger回放录制线程(七)

AndioFlinger 作为 Android 的音频系统引擎,重任之一是负责输入输出流设备的管理及音频流数据的处理传输,这是由回放线程 PlaybackThread 及其派生的子类和录制线程 RecordThread 进行的。 一、基础介绍 1、关系图 ThreadBase:PlaybackThread 和 RecordThread 的基类。 Re…

群晖NAS使用Docker部署WPS Office结 合内网穿透实现远程编辑本地文档

文章目录 1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 wps-office是一个在Linux服务器上部署WPS Office的镜像。它基于WPS Office的Linux版本&#xff0c;通过…

redis--redis Cluster

简介 解决了redis单机写入的瓶颈问题&#xff0c;即单机的redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素无中心架构的redis cluster机制&#xff0c;在无中心的redis集群当中&#xff0c;其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连…

Redis机制-Redis互斥锁、分布式锁

目录 一 互斥锁 二 分布式锁 Redis实现分布式锁 redisson实现分布式锁 可重入性&#xff1a; 主从一致性&#xff08;性能差&#xff09;&#xff1a; 一 互斥锁 假设我们现在有一个业务要实现秒杀优惠券的功能&#xff0c;如果是一个正常的流程&#xff0c;线程之间应该…

ThreadLocal为什么会导致内存泄漏?

问题引出&#xff1a; ThreadLocal是为了解决什么问题而产生的&#xff1f; ThreadLocal发生内存泄漏的根本原因是什么&#xff1f; 如何避免内存泄漏的发生&#xff1f;定义 为了解决多个线程同时操作程序中的同一个变量而导致的数据不一致性的问题。   假设现在有两个线程A…

【C++题解】1696. 请输出1~n之间所有的整数

问题:1696. 请输出1~n之间所有的整数 类型&#xff1a;循环 题目描述&#xff1a; 从键盘读入一个整数 &#x1d45b;n &#xff0c;请循环输出 1∼n 之间所有的整数&#xff0c;每行输出 1 个。 比如&#xff0c;假设 n5 &#xff0c;那么输出结果如下&#xff1a; 1 2 3 4 …