首页 > 编程语言 >Python——数据结构与算法-时间复杂度&空间复杂度-链表&树状结构

Python——数据结构与算法-时间复杂度&空间复杂度-链表&树状结构

时间:2024-11-06 20:45:53浏览次数:4  
标签:node None Python 复杂度 self 链表 next 节点

1.数据结构和算法简介

  • 程序

    可以理解为:程序 = 数据结构 + 算法

  • 概述/目的:
    都可以提高程序的效率(性能)

  • 数据结构

    指的是 存储, 组织数据的方式.

  • 算法

    指的是 为了解决实际业务问题而思考 思路和方法, 就叫: 算法.

2.算法的5大特性介绍

  • 概述:
    为了解决实际业务问题, 而考虑出来的方法和思路, 就叫: 算法.
    算法具有独立性, 即: 它是解决问题的思路(思想)和方法, 不依赖于语言

  • 5大特性

    • 有输入, 需要传入1或者多个参数
    • 有输出, 需要返回1个或者多个结果
    • 有穷性, 执行一定次数循环后, 会自动终止, 不会死循环.
    • 确定性, 每一步都有其具体的含义, 不会出现二义性.
    • 可行性, 每一步都是可执行的, 且会在一定次数后结束.
    问: 如何衡量算法的优劣?
        答案:
            不能单纯的只依靠程序的执行时间, 因为程序执行时也会受到机器, 硬件, 其它软件的影响.
            所以我们可以假定 计算机执行每个步骤的时间都是固定的, 只考虑算法的 执行步骤即可.
            即:  算法的总执行时间 = 算法的总执行步骤 * 每个步骤执行的时间
    

3.时间复杂度介绍:

​ 概述:
​ 它可以反应1个算法的优劣, 它表示1个算法随着问题规模的变化而表现出来的趋势.

 细节:
        1. 如非特殊说明, 我们考虑时间复杂度都是考虑: 最坏时间复杂度, 它算是算法的一种保证.
        2. 常见的时间复杂度, 效率从高到低分别是:
            O(1) > O(logn) > O(n) > O(nlogn) > O(n²) > O(n³)
        3. 空间复杂度(了解)指的是: 算法的运算过程中, 临时占用空间的大小, 也是用大O标记法标记的, 具体如下:
            O(1) < O(logn) < O(n) < O(n²) < O(n³)
        4. 扩展一个开发思想, 叫: 时空转换, 即: 拿时间 换 空间, 还是 拿空间 换 时间.
        5. 程序 = 数据结构 + 算法

大O标记法:
​ 忽略次要条件, 只考虑主要条件(随着问题规模变化而变化的内容), 就会得到: 大O标记法, 标记的效率.
​ 例如, 如下的代码:

import time
# 需求: 已知 a + b + c = 1000, 且 a^2 + b^2 = c^2, 请求出 a, b, c可能得所有组合.
# 1. 获取开始时间.
start = time.time()
# 2. 具体的计算过程

# # 方式1: 穷举法实现, 241秒
# for a in range(1001):
#     for b in range(1001):
#         for c in range(1001):
#             if a ** 2 + b ** 2 == c ** 2 and a + b + c == 1000:
#                 print(a, b, c)

# 方式2: 穷举法实现, 123秒
# for a in range(1001):
#     for b in range(1001):
#         for c in range(1001):
#             if a + b + c == 1000 and a ** 2 + b ** 2 == c ** 2:
#                 print(a, b, c)

# 方式3: 代入法, 0.3秒
for a in range(1001):
    for b in range(1001):
        c = 1000 - a - b
        if a ** 2 + b ** 2 == c ** 2:
            print(a, b, c)

        if a ** 2 + b ** 2 == c ** 2:
            print(a, b, c)

# 3. 获取结束时间.
end = time.time()
# 4. 打印结果.
print(f"耗时: {end - start} 秒!")

4.数据结构

数据结构介绍:
    概述:
        数据结构 = 存储 和 组织数据的 方式.
    分类:
        线性结构
        非线性结构

线性结构:
    特点:
        每个节点只能有1个子节点(后继节点) 和 1个父节点(前驱节点).
    代表:
        栈, 队列, 链表...
    分类:
        顺序表
        链表

线性结构之顺序表介绍:
    概述:
        它属于线性结构的一种, 例如: 栈, 队列都属于顺序表.
    特点:
        所有元素在内存中以 连续的内存空间 来存储.
    举例:
        你们部门出去旅游, 共10个人, 开10个房间, 要求: 10个房间在同一层, 且是连续的房间.
    根据存储数据的方式, 又分为:
        一体式存储: 地址值 和 数据存储在一起.
        分离式存储: 地址值 和 数据分开存储.
    顺序表-扩容策略解释:
        1. 每次扩容增加固定的条数目.    属于拿时间 换 空间.
        2. 每次扩容容量翻倍.           属于拿空间 换 时间.
        细节:
            顺序表主要存储 数据区 和 信息区,  数据区和信息区在一起的叫: 一体式存储, 分开存储的叫: 分离式存储.
    顺序表的增删操作:
        方式1: 末尾增删.          时间复杂度: O(1)
        方式2: 中间增删(非保序)    时间复杂度: O(1)
        方式3: 中间增删(保序)      时间复杂度: O(n)
        
树状结构(Tree)介绍:
    概述:
        它属于数据结构之 非线性结构的一种, 父节点可以多个子节点(后继节点).
    特点:
        1. 有且只能有1个根节点.
        2. 每个节点都可以有1个父节点及任意个子节点. 前提: 根节点除外.
        3. 没有子节点的节点称之为: 叶子节点.
    二叉树介绍:
        概述:
            每个节点最多只能有2个子节点.
        分类:
            完全二叉树:  除了最后1层, 其它层的节点都是满的.
            满二叉树:    包括最后1层, 所有层的节点都是满的.
            不完全二叉树: 某层(不仅仅是最后1层)的节点数量不满.
        常用的二叉树:
            平衡二叉树:  防止树退化成链表.  指的是: 任意节点的两颗子树的高度差不超过1.
            排序二叉树:  主要是对元素排序的.
        存储方式:
            更推荐使用 链表的方式来存储, 每个节点由3部分组成, 分别是: 元素域(数值域), 左子树(地址域), 右子树(地址域)
            针对于 多叉树的情况, 可以将其转成二叉树, 然后再来存储.

1.链表

链表是一种重要的线性数据结构,它不同于数组,以动态分配的方式存储数据。每个节点包含数据部分和指向下一个节点的指针,因此链表不需要连续的内存空间,可以方便地进行插入和删除操作。下面详细介绍链表的概念、类型、操作及其实现。

链表的基本概念

链表由一系列节点组成,每个节点包含两部分:

  1. 数据(data): 存储节点的数据。
  2. 指针(next): 存储指向下一个节点的引用。

链表的第一个节点称为头节点(head),最后一个节点的next指针指向None,表示链表结束。

链表的优势: 相比数组,链表在插入和删除操作上更加高效,尤其是在头部和尾部的操作。链表不需要连续的内存空间。
链表的劣势: 链表的查找效率较低,必须从头节点开始逐个遍历。此外,由于每个节点需要额外存储指针,链表的内存开销相对较高。


单向链表: 每个节点由 1个数值域和1个地址域组成, 且每个节点的地址域指向下个节点的地址. 最后1个节点的地址域为: None

单向循环链表: 每个节点由 1个数值域和1个地址域组成, 且每个节点的地址域指向下个节点的地址. 最后1个节点的地址域为: 第1个节点的地址

双向链表: 每个节点由 1个数值域和2个地址域组成, 且每个节点的地址域分别指向前1个节点的地址 和 后1个节点的地址.
		第1个节点的(前)地址域为: None,  最后1个节点的(后)地址域为: None

双向循环链表:每个节点由 1个数值域和2个地址域组成, 且每个节点的地址域分别指向前1个节点的地址 和 后1个节点的地址.
            第1个节点的(前)地址域为: 最后1个节点的地址,  最后1个节点的(后)地址域为: 第1个节点的地址.
链表的类型
  1. 单向链表(Singly Linked List)
    • 每个节点只包含指向下一个节点的指针。
    • 操作简单,但只能从头节点开始逐个遍历到末尾。
  2. 双向链表(Doubly Linked List)
    • 每个节点包含两个指针:一个指向下一个节点,一个指向前一个节点。
    • 这种结构使得可以双向遍历链表,插入和删除更加灵活。
  3. 循环链表(Circular Linked List)
    • 链表中的最后一个节点的next指针指向头节点,形成一个环。
    • 循环链表可以是单向的或双向的,适合某些需要循环处理数据的场景。
  4. 带头节点和不带头节点的链表
    • 带头节点:链表在第一个有效节点前有一个头节点,头节点不存储数据,但使操作更方便。
    • 不带头节点:链表的第一个节点就是第一个数据节点。
链表的基本操作
  1. 创建链表 创建链表时需要初始化链表的头节点,通常可以通过一个类来实现。
  2. 插入节点
    • 头插法:在链表头部插入节点。
    • 尾插法:在链表尾部插入节点。
    • 中间插入:在指定位置插入节点。
  3. 删除节点
    • 头节点删除:删除头节点并将头指针指向下一个节点。
    • 尾节点删除:删除尾节点,找到倒数第二个节点并将其next指向None
    • 中间删除:删除链表中指定位置的节点。
  4. 查找节点 遍历链表,找到数据与目标匹配的节点。
  5. 遍历链表 从头节点开始,顺序访问链表中的每个节点,直到链表末尾(单向链表)或循环一周(循环链表)。

单向链表

# 定义链表的节点类
class Node:
    def __init__(self, data):
        # 节点包含两个属性:数据和指向下一个节点的指针
        self.data = data  # 存储节点的数据
        self.next = None  # 存储下一个节点的引用,初始为None

# 定义单向链表类
class SinglyLinkedList:
    def __init__(self):
        # 初始化链表时,链表为空,因此头节点设置为None
        self.head = None

    # 在链表头部插入节点
    def insert_at_head(self, data):
        # 创建新节点,将数据存储在节点中
        new_node = Node(data)
        # 新节点的next指针指向当前的头节点
        new_node.next = self.head
        # 更新头节点为新节点,表示链表的起点发生了改变
        self.head = new_node

    # 在链表尾部插入节点
    def insert_at_end(self, data):
        # 创建新节点,数据存储在节点中
        new_node = Node(data)
        # 先检查链表是否为空。如果链表为空,则直接将新节点作为头节点
        if not self.head:
            self.head = new_node
            return
        # 如果链表非空,遍历链表直到找到最后一个节点,将最后一个节点的next指针指向新节点
        last_node = self.head
        while last_node.next:
            last_node = last_node.next
        # 将最后一个节点的next指向新节点
        last_node.next = new_node

    # 删除具有特定数据的节点
    def delete_node(self, key):
        # 用临时变量指向头节点
        temp = self.head
        
        # 先检查头节点是否为要删除的节点。如果头节点就是要删除的节点
        if temp and temp.data == key:
            # 将头节点指向下一个节点(删除头节点)
            self.head = temp.next
            temp = None  # 释放被删除节点的内存
            return
        
        # 否则,查找要删除的节点
        prev = None  # 保存当前节点的前一个节点
        while temp and temp.data != key:
            prev = temp
            temp = temp.next
        
        # 如果没有找到节点
        if temp is None:
            return
        
        # 将前一个节点的next指向要删除节点的下一个节点
        prev.next = temp.next
        temp = None  # 释放被删除节点的内存
        
    # 指定位置 添加元素
    def insert(self, pos, item):
        if pos <= 0:
            self.add(item)
        elif pos >= self.length():
            self.append(item)
        else:
            # 从头开始遍历
            cur = self.head
            # 初始位置为 0
            count = 0
            # 找到要插入 位置的前一个索引
            while count < pos-1:
                cur = cur.next
                count += 1
            # 此时已经找到
            # 将新节点的next指针指向插入位置原来的下一个节点。然后,将前一个节点的next指针指向新节点。
            new_node = SingleNode(item)
            new_node.next = cur.next
            cur.next = new_node

    # 查找链表中是否存在特定数据
    def search(self, key):
        # 用临时变量指向头节点
        current = self.head
        # 遍历链表,查找节点数据是否等于key
        while current:
            if current.data == key:
                return True  # 找到数据,返回True
            current = current.next  # 移动到下一个节点
        return False  # 未找到数据,返回False

    # 遍历并打印链表中的所有节点
    def traverse(self):
        # 用临时变量指向头节点
        current = self.head
        # 遍历链表,打印每个节点的数据
        while current:
            print(current.data, end=" -> ")
            current = current.next
        print("None")  # 最后输出None表示链表结束

# 测试链表功能
linked_list = SinglyLinkedList()

# 插入节点到链表头部
linked_list.insert_at_head(3)  # 链表:3 -> None
linked_list.insert_at_head(2)  # 链表:2 -> 3 -> None

# 插入节点到链表尾部
linked_list.insert_at_end(4)   # 链表:2 -> 3 -> 4 -> None

# 遍历链表
linked_list.traverse()  # 输出: 2 -> 3 -> 4 -> None

# 删除节点
linked_list.delete_node(3)     # 删除值为3的节点,链表变为:2 -> 4 -> None

# 遍历链表
linked_list.traverse()  # 输出: 2 -> 4 -> None

# 搜索节点
print(linked_list.search(2))   # 输出: True
print(linked_list.search(3))   # 输出: False


双向链表

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
        self.prev = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None

    def insert_at_head(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        self.head.prev = new_node
        new_node.next = self.head
        self.head = new_node

    def insert_at_end(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            return
        last_node = self.head
        while last_node.next:
            last_node = last_node.next
        last_node.next = new_node
        new_node.prev = last_node

    def delete_node(self, key):
        temp = self.head
        if temp and temp.data == key:
            self.head = temp.next
            if self.head:
                self.head.prev = None
            temp = None
            return
        while temp and temp.data != key:
            temp = temp.next
        if temp is None:
            return
        if temp.next:
            temp.next.prev = temp.prev
        if temp.prev:
            temp.prev.next = temp.next
        temp = None

    def traverse(self):
        current = self.head
        while current:
            print(current.data, end=" <-> ")
            current = current.next
        print("None")

# 测试
dll = DoublyLinkedList()
dll.insert_at_head(1)
dll.insert_at_end(2)
dll.insert_at_end(3)
dll.traverse()  # 输出: 1 <-> 2 <-> 3 <-> None
dll.delete_node(2)
dll.traverse()  # 输出: 1 <-> 3 <-> None

2.树状结构(Tree)介绍:

​ 概述:
​ 它属于数据结构之 非线性结构的一种, 父节点可以多个子节点(后继节点).

特点:
1. 有且只能有1个根节点.
2. 每个节点都可以有1个父节点及任意个子节点. 前提: 根节点除外.
3. 没有子节点的节点称之为: 叶子节点.

二叉树介绍:
        概述:
            每个节点最多只能有2个子节点.
        分类:
            完全二叉树:  除了最后1层, 其它层的节点都是满的.
            满二叉树:    包括最后1层, 所有层的节点都是满的.
            不完全二叉树: 某层(不仅仅是最后1层)的节点数量不满.
        常用的二叉树:
            平衡二叉树:  防止树退化成链表.  指的是: 任意节点的两颗子树的高度差不超过1.
            排序二叉树:  主要是对元素排序的.
        存储方式:
            更推荐使用 链表的方式来存储, 每个节点由3部分组成, 分别是: 元素域(数值域), 左子树(地址域), 右子树(地址域)
            针对于 多叉树的情况, 可以将其转成二叉树, 然后再来存储.
"""
# 案例: 自定义代码, 模拟树状结构.
# 1. 定义节点类.
class Node(object):
    # 初始化属性
    def __init__(self, item):
        self.item = item  # 数值域, 存储节点内容的
        self.lchild = None  # 节点的 左子树(的地址), left
        self.rchild = None  # 节点的 右子树(的地址), right


# 2. 创建 二叉树类.
class BinaryTree(object):
    # 2.1 初始化属性
    def __init__(self, root=None):
        self.root = root  # 充当根节点

    # 2.2 定义add函数(), 表示往: 添加元素
    def add(self, item):
        # 1. 判断根节点是否存在, 如果不存在, 则该(新节点)就是 根节点.
        if self.root is None:
            self.root = Node(item)
            return  # 细节: 添加后, 本次添加动作完毕, 记得终止.

        # 2. 走到这里, 说明根节点存在, 我们需要找到 "缺失的节点", 就是新节点要添加的位置.
        # 创建1个队列, 用于记录已存在的节点.
        queue = []
        # 把根节点加到队列中.
        queue.append(self.root)

        # 3.循环遍历队列, 直至 把新元素添加到合适的位置.
        while True:
            # 4. 获取队列的第1个元素(如果首次操作, 则是在获取 根节点)
            node = queue.pop(0)
            # 5. 判断当前节点的左子树是否存在.
            if node.lchild is None:
                # 5.1 如果当前节点的 左子树不存在, 就把新节点添加到这里.
                node.lchild = Node(item)
                return  # 细节: 添加后, 本次添加动作完毕, 记得终止.
            else:
                # 5.2 如果当前节点的 左子树存在, 就将其添加到队列中.
                queue.append(node.lchild)

            # 6. 判断当前节点的右子树是否存在.
            if node.rchild is None:
                # 6.1 如果当前节点的 右子树不存在, 就把新节点添加到这里.
                node.rchild = Node(item)
                return  # 细节: 添加后, 本次添加动作完毕, 记得终止.
            else:
                # 6.2 如果当前节点的 右子树存在, 就将其添加到队列中.
                queue.append(node.rchild)

    # 2.3 定义 breadth_travel(), 表示: 广度优先遍历
    def breadth_travel(self):
        # 1. 判断根节点是否存在.
        if self.root is None:
            return  # 根节点不存在, 结束遍历即可.

        # 2. 走到这里, 根节点存在, 创建队列, 记录所有的节点.
        queue = []
        queue.append(self.root)

        # 3. 只要队列中有内容, 就说明还有节点, 就继续循环.
        while len(queue) > 0:
            # 4. 获取队列的第1个元素.
            node = queue.pop(0)
            # 5. 打印该节点的内容.
            print(node.item, end='\t')
            # 6. 判断当前节点的左, 右子树是否存在, 存在就添加到队列中.
            if node.lchild is not None:
                queue.append(node.lchild)
            if node.rchild is not None:
                queue.append(node.rchild)

    # 2.4 定义 preorder_travel(), 表示: 深度优先遍历之 先序(根左右)
    def preorder_travel(self, root):
        # 判断 根节点是否存在 存在则获取元素
        if root is not None:
            # 先序的顺序: 根 -> 左 -> 右
            print(root.item, end=' ')   # 根
            # 递归方式, 获取 子左树的所有元素
            self.preorder_travel(root.lchild)
            # 递归方式, 获取 子右树的所有方式
            self.preorder_travel(root.rchild)

    # 2.5 定义 inorder_travel(), 表示: 深度优先遍历之 中序(左根右)
    def inorder_travel(self, root):
        if root is not None:
            self.inorder_travel(root.lchild)
            print(root.item, end=' ')   # 根
            self.inorder_travel(root.rchild)

    # 2.6 定义 postorder_travel(), 表示: 深度优先遍历之 后序(左右根)
    def postorder_travel(self, root):
        if root is not None:
            self.postorder_travel(root.lchild)
            self.postorder_travel(root.rchild)
            print(root.item, end=' ')


# 3. 定义 demo01_测试节点类和二叉树类()
def demo01_测试节点类和二叉树类():
    # 3.1 创建节点对象.
    node1 = Node('乔峰')
    # 3.2 打印节点的 数值域 和 地址域
    print(f'节点的地址: {node1}')
    print(f'节点的内容: {node1.item}')
    print(f'节点的左子树(地址): {node1.lchild}')
    print(f'节点的右子树(地址): {node1.rchild}')

    # 3.3 创建二叉树对象.
    bt = BinaryTree()
    print(f'根节点: {bt.root}')  # None
    print('-' * 21)

    bt2 = BinaryTree(node1)
    print(f'根节点: {bt2.root}')
    print(f'根节点的内容: {bt2.root.item}')
    print(f'根节点的左子树(地址): {bt2.root.lchild}')
    print(f'根节点的右子树(地址): {bt2.root.rchild}')


# 4. 定义 demo02_演示队列的使用()
def demo02_演示队列的使用():
    # 4.1 创建列表对象, "模拟"队列, 即: 先进先出.
    queue = []
    # 4.2 往队列中添加元素
    queue.append('A')
    queue.append('B')
    queue.append('C')
    # 4.3 打印队列的内容.
    print(queue)
    # 4.4 逐个获取队列中的内容, 模拟: 先进先出.
    # pop()函数: 根据索引, 删除(弹出)列表中的元素, 并返回该元素.
    print(queue.pop(0))  # ['A', 'B', 'C'] => ['B', 'C'], 返回: 'A'
    print(queue.pop(0))  # ['B', 'C'] => ['C'], 返回: 'B'
    print(queue.pop(0))  # ['C'] => [], 返回: 'C'


# 5. 定义 demo03_演示广度优先()
def demo03_演示广度优先():
    # 1. 创建二叉树.
    bt = BinaryTree()
    # 2. 添加元素到二叉树中.
    bt.add('A')
    bt.add('B')
    bt.add('C')
    bt.add('D')
    bt.add('E')
    bt.add('F')
    bt.add('G')
    bt.add('H')
    # 3. 广度优先的方式遍历.
    bt.breadth_travel()


# 6. 定义demo04 演示深度优先遍历
def demo04_演示深度优先遍历():
    # 1. 创建二叉树
    bt = BinaryTree()
    # 2. 添加元素到二叉树中
    bt.add(1)
    bt.add(2)
    bt.add(3)
    bt.add(4)
    bt.add(5)
    bt.add(6)
    bt.add(7)
    bt.add(8)
    bt.add(9)
    # 3. 深度优先的方式遍历
    print('先序 遍历结果:')
    bt.preorder_travel(bt.root)

    print('\n中序 遍历结果: ')
    bt.inorder_travel(bt.root)

    print('\n后序 遍历结果: ')
    bt.inorder_travel(bt.root)


# 7. 测试代码.
if __name__ == '__main__':
    # demo01_测试节点类和二叉树类()
    # demo02_演示队列的使用()
    # demo03_演示广度优先()
    demo04_演示深度优先遍历()
    

标签:node,None,Python,复杂度,self,链表,next,节点
From: https://blog.csdn.net/m0_74893204/article/details/143466474

相关文章

  • python面向对象(一)
    前言Python是一种功能强大的编程语言,因其简洁的语法和强大的库而备受开发者喜爱。而在Python中,面向对象编程(OOP)是一种核心的编程范式,它通过模拟现实世界中的对象和交互来帮助我们设计清晰、易维护的代码。在本篇博客中,我们将深入探讨Python的面向对象编程的基本概念,了解如......
  • 【PAT_Python解】1114 全素日
    原题链接:PTA|程序设计类实验辅助教学平台Tips:以下Python代码仅个人理解,非最优算法,仅供参考!多学习其他大佬的AC代码!defis_prime(n):ifn<=3:returnn>=2ifn%6notin(5,1):returnFalseforiinrange(5,int(n**0.5)+1,6):......
  • 【PAT_Python解】1110 区块反转
    原题链接:PTA|程序设计类实验辅助教学平台Tips:以下Python代码仅个人理解,非最优算法,仅供参考!多学习其他大佬的AC代码!importsys#读取输入head,n,k=map(int,sys.stdin.readline().split())#初始化数据,装入字典,最终取值data={}next={}for_inrange(n):......
  • 【PAT_Python解】1113 钱串子的加法
    原题链接:PTA|程序设计类实验辅助教学平台Tips:以下Python代码仅个人理解,非最优算法,仅供参考!多学习其他大佬的AC代码!defadd_base30(num1,num2):max_length=max(len(num1),len(num2))#在前面补零,使两个字符串长度相同num1=num1.zfill(max_lengt......
  • 0基础学Python——类的单例模式、反射函数、记录类的创建个数、迭代器、生成器及生成
    0基础学Python——类的单例模式、反射函数、记录类的创建个数、迭代器、生成器及生成器练习类的单例模式定义代码演示反射函数代码演示记录类的创建个数迭代器定义特点生成器定义特点写法生成器练习生成器生成1-无穷的数字生成器生成无穷个素数类的单例模式定义......
  • 0基础学Python——面向对象-可迭代、面向对象-迭代器、call方法、call方法实现装饰器
    0基础学Python——面向对象-可迭代、面向对象-迭代器、call方法、call方法实现装饰器、计算函数运行时间面向对象--可迭代实现方法面向对象--迭代器实现方法call方法作用call方法实现装饰器代码演示计算函数运行时间代码演示面向对象–可迭代把对象看做容器,存储......
  • 基于卷积神经网络的柑桔病害识别与防治系统,resnet50,mobilenet模型【pytorch框架+pytho
     更多目标检测和图像分类识别项目可看我主页其他文章功能演示:柑橘病害识别与防治系统,卷积神经网络,resnet50,mobilenet【pytorch框架,python源码】_哔哩哔哩_bilibili(一)简介基于卷积神经网络的柑桔病害识别与防治系是在pytorch框架下实现的,这是一个完整的项目,包括代码,数据集,......
  • Python 日志分级记录到不同文件的实现
    Python日志分级记录到不同文件的实现介绍如何使用Python的logging模块,按INFO、WARNING和ERROR级别将日志记录到不同的文件中。通过封装CustomLogger类,方便在项目中直接调用,简化日志管理。1.实现目标分级日志记录:将INFO、WARNING、ERROR级别的日志分别记录到不......
  • python球探数据分析
    Python球探数据分析入门指南作为一名刚入行的小白,你可能会对如何使用Python进行球探数据分析感到困惑。不用担心,这篇文章将为你提供一份详细的入门指南,帮助你逐步掌握这项技能。流程概览首先,让我们通过一个表格来了解整个数据分析的流程:步骤描述1获取数据2数据......
  • Leetcode刷题Python之3254.长度为K的子数组的能量值I
    提示:关于数组子问题的挑战,涉及能量值的计算。文章目录一、问题描述示例二、解题思路三、代码实现1.引入库2.代码解释总结一、问题描述给定一个长度为n的整数数组nums和一个正整数k,我们需要计算每个长度为k的子数组的能量值。能量值的定义如下:如果子数......