当前位置: 首页 > news >正文

Python学习笔记(列表相关操作)

列表相关操作

  • 第17节课 列表相关操作
    • 1 常规操作
    • 2 查找操作
    • 3 排序操作

第17节课 列表相关操作

无论是内置函数、对象函数,用起来确实很方便,但是作为初学者,你必须懂得它们背后的运行逻辑!

1 常规操作

(1)遍历

arr = [1,2,3,4]
# 以索引遍历:可以在遍历期间修改元素
for index in range(len(arr)):
    arr[index] = arr[index] ** 2
    print(arr[index])
print(arr)

# 以元素遍历:只能获取元素,不能修改元素值(可变对象除外)
for element in arr:
    print(element)

# 同时遍历角标和元素
for index, element in enumerate(arr):
    print(f"角标{index},元素{element}")

# 反向遍历
for index in range(len(arr) - 1, -1, -1):
    print(arr[index])

(2)最值

def min_max(arr:list[int]) -> tuple:
    min_value = arr[0]
    max_value = arr[0]
    for i in range(1, len(arr)):
        if arr[i] > max_value:
            max_value = arr[i]
        if arr[i] < min_value:
            min_value = arr[i]

    return min_value, max_value

arr = [2,9,8,1,7,4,6,3,5]
min_val, max_val = min_max(arr)
print(min_val, max_val)

(3)存在性

arr = [2,9,8,1,7,4,6,3,5] 
#O(n)
def is_exist(arr:list[int], key:int) -> bool:
    for element in arr:
        if element == key:
            return True
    return False

print(is_exist(arr, 10))
print(is_exist(arr, 8))

(4)反转

arr = [1,2,3,4,5,6,7,8,9]
"""
1 2 3 4 5 6 7 8 9
        l
        r
"""
def list_reverse(arr:list[int]) -> None:
    l = 0
    r = len(arr) - 1
    while l < r:
        arr[l], arr[r] = arr[r], arr[l]
        l += 1
        r -= 1

list_reverse(arr)
print(arr)

(5)乱序

import random
arr = [1,2,3,4,5,6,7,8,9]

def list_shuffle(arr):
    for i in range(len(arr)):
        j = random.randint(0, len(arr) - 1)
        arr[i], arr[j] = arr[j], arr[i]

list_shuffle(arr)
print(arr)

(6)二维列表

所谓的二维列表,其实本质上就是一个一维列表,只不过该一维列表中的每一个元素为其他的一维列表

def print_matrix(matrix):
    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            print(matrix[i][j], end = ' ')
        print()
# 直接填值创建二维列表
matrix = [[1,2,3], [4,5,6], [7,8,9]]
print(len(matrix))
print(len(matrix[1]))
print_matrix(matrix)
matrix = [
    [1,2,3,4],
    [1,2,3],
    [1,2],
    [1]
]
print_matrix(matrix)

# 循环创建二维列表 指定默认值 0
rows = 3
cols = 5
matrix = []
for i in range(rows):
    row = [0] * cols
    matrix.append(row)
matrix[2][2] = 6
print_matrix(matrix)

# 列表推导式创建二维列表
matrix = [[0] * cols for _ in range(rows)]
matrix[2][2] = 6
print_matrix(matrix)

matrix = [ [i + j for j in range(cols)] for i in range(rows)]
print_matrix(matrix)

2 查找操作

(1)二分查找
在这里插入图片描述

前提数据必须是有序的(升序、降序)

# 返回的是元素key在arr中的角标 如果不存在则返回-1
def binary_search(arr, key): #O(log n)
    left = 0
    right = len(arr) - 1
    mid = (left + right) // 2
    while arr[mid] != key:
        if arr[mid] < key:
            left = mid + 1
        elif key < arr[mid]:
            right = mid - 1
        if left > right:
            return -1
        # 重新更新mid的值
        mid = (left + right) // 2
    return mid

# 顺序查找
def linear_search(arr, key):
    for index in range(len(arr)):
        if arr[index] == key:
            return index
    return -1

# arr = [1,2,3,4,5,6,7,8,9]
# key = 6
# print(binary_search(arr, key))
"""
n/2/2/2/2/..../2 = 1
n/2^x = 1
n = 2^x
x = logn
"""
arr = []
for i in range(70000000):
    arr.append(i)
key = 69999999
print("数据创建完毕...")
print(binary_search(arr, key))
print(linear_search(arr, key))

(2)插值查找

前提数据必须是有序的(升序、降序),它是二分查找的升级版本

# mid = (key - arr[left]) / (arr[right] - arr[left]) * (right - left) + left
# 当数据分布比较均匀的时候 大致满足等差序列的情况 性能要比二分查找要优秀
def interpalotion_search(arr, key):
    count = 0
    left = 0
    right = len(arr) - 1
    mid = 0
    # mid = int((key - arr[left]) / (arr[right] - arr[left]) * (right - left)) + left
    # while arr[mid] != key:
    #     count += 1
    #     if arr[mid] < key:
    #         left = mid + 1
    #     elif key < arr[mid]:
    #         right = mid - 1
    #     if left > right:
    #         mid  = -1
    #         break
    #     mid = int((key - arr[left]) / (arr[right] - arr[left]) * (right - left)) + left
    while True:
        count += 1
        mid = int((key - arr[left]) / (arr[right] - arr[left]) * (right - left)) + left
        # key本身在范围外 没找到
        if mid < left or mid > right:
            mid = -1
            break
        if arr[mid] < key:
            left = mid + 1
        elif key < arr[mid]:
            right = mid - 1
        else:
            break
        # 在范围内没找到
        if left > right:
            mid  = -1
            break
    print(f"插值查找count={count}")
    return mid

def binary_search(arr, key): #O(log n)
    count = 0
    left = 0
    right = len(arr) - 1
    mid = (left + right) // 2
    while arr[mid] != key:
        count += 1
        if arr[mid] < key:
            left = mid + 1
        elif key < arr[mid]:
            right = mid - 1
        if left > right:
            mid = -1
            break
        # 重新更新mid的值
        mid = (left + right) // 2
    print(f"二分查找count={count}")
    return mid
# int((20 - 1)/(20-1) * (19 - 0)) + 0 = 19
# int((100 - 1)/(20 - 1) * (19 - 0))+ 0 = 99
# int((-100 - 1)/(20 - 1)*(19-0)) + 0 = - 101
arr= [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
key = -100
print(binary_search(arr, key))
print(interpalotion_search(arr, key))

3 排序操作

希尔排序、堆排序、快速排序、归并排序、计数排序、基数排序、桶排序

(1)选择排序
在这里插入图片描述

# 选择排序 O(n^2)
"""
从前往后 每一个元素都要跟其后面的其他元素作比较
如果出现左大右小 则进行交换
"""
def selection_sort(arr):
    for i in range(len(arr) - 1): # 少一轮
        for j in range(i + 1, len(arr)):
            if arr[i] > arr[j]:
                arr[i], arr[j] = arr[j], arr[i]
arr = [5,2,3,1,4]
selection_sort(arr)
print(arr)

(2)冒泡排序
在这里插入图片描述

# 冒泡 O(n^2)
"""
从前往后 元素之间两两进行比较 
如果左大右小则交换
"""
def bubble_sort(arr):
    # 0 1 2 3
    for i in range(len(arr) - 1): #-1 少一轮
        for j in range(len(arr) - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]

arr = [5,2,3,1,4]
bubble_sort(arr)
print(arr)

(3)插入排序

# 选择 O(n^2)
def insertion_sort(arr):
    # 从第2个元素开始遍历
    for i in range(1, len(arr)):
        j = i
        while j > 0 and arr[j - 1] > arr[j]:
            arr[j - 1], arr[j] = arr[j], arr[j - 1]
            j -= 1
arr = [5,2,3,1,4]
insertion_sort(arr)
print(arr)

根据循环的特性来去解决特定的问题,而不是学习循环本身,学算法思想!

循环之间的好坏其实也有区别,主要在于数据的分布情况

(1)大致升序

(2)大致降序

(3)趋于稳定(方差小,相等值比较多)

(4)完全随机

用time模块记录一下运行时间

相关文章:

  • 供应商涨价,项目如何控制采购成本
  • ⑫交换机引流设备案例
  • What Was the “Game Genie“ Cheat Device, and How Did It Work?
  • ViT 模型讲解
  • 【Java八股】
  • 3.2.2.2 Spring Boot配置视图控制器
  • 机器学习项目三:颜色检测
  • Java老鼠迷宫(递归)---案例来自韩顺平老师讲Java
  • Neo4j GDS-11-neo4j GDS 库中相似度算法实现
  • 鸿蒙开发-ArkUi控件使用
  • 重学Redis:Redis常用数据类型+存储结构(源码篇)
  • 5.5 GitHub数据秒级分析核心揭秘:三层提示工程架构设计解析
  • 日志文件爆满_配置使用logback_只保留3天日志文件_每天定时生成一个日志文件---SpringCloud工作笔记206
  • 如何制定有效的风险应对计划
  • C++ std::string_view介绍及性能提升分析
  • android面试情景题详解:android如何处理断网、网络切换或低速网络情况下的业务连续性
  • 关于SENSOR 720P/1080P 静电保护方案
  • Python静态方法和类方法详解
  • 在断网的时候,websocket 一直在CLOSING 状态
  • 如何制定合理的项目预算
  • 上海又现昆虫新物种:体长仅1.5毫米,却是凶猛的捕食者
  • 中央民族乐团团长赵聪已任文旅部艺术司司长
  • 今年一季度,上海对东盟进出口总值同比增长7.1%
  • 一季度浙江实现生产总值22300亿元,同比增长6.0%
  • 《“四有”好老师系列丛书》发布,由顾明远总主编
  • 广西:启动旱灾防御三级应急响应