萱仔求职系列——2.1 python基础知识复习——数据类型+数据结构

        这几天疯狂面试,每天都接到新的面试,是时候复习一下我的python基础了,虽然平时做项目的时候用的都是一些库,加上自己时常不注重基础,以至于面试的时候有的非常详细的基础部分反倒扯后腿,被某宇宙大厂面试官建议虽然可能进公司之后不需要这么细节,但是面试的时候还是应该更熟悉基础。(心痛

        所以我在这里总结一些常用的基础,和一些非常常用的数据结构算法代码,自己复习的同时也记录一下。

以下基础用一些题目进行辅助理解

面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

1.python数据类型

在 Python 中,数据类型可以分为基本数据类型和容器数据类型。以下是对 Python 中主要 9 种数据类型的详细讲解:

1. Int(整型)

  • 描述:整型(int)用于表示整数,支持正数、负数和零。Python 中的整型可以表示任意大小的整数,内存大小仅受限于机器的可用内存。
  • 操作
    • 加法、减法、乘法、除法
    • 幂运算:**
    • 整数除法://
    • 取模:%

2. Float(浮点型)

  • 描述:浮点型(float)用于表示带有小数部分的数字,符合 IEEE 754 标准的双精度浮点数。浮点型通常用于需要精度较高的数值运算。
    • 符号位(Sign Bit):用于表示数值的正负。0 表示正数,1 表示负数。

    • 指数部分(Exponent):表示浮点数的数量级。它的值通过偏移量(bias)来存储,通常是 127 对于 32 位浮点数(单精度)和 1023 对于 64 位浮点数(双精度)。

    • 尾数部分(Mantissa/Significand):表示有效数字部分,通常是一个二进制小数。尾数部分的表示是归一化的,即最前面为 1 的二进制数默认为 1,所以通常不需要显式存储。

  • 操作
    • 加法、减法、乘法、除法
    • 幂运算:**
    • 科学计数法表示:1.23e4 表示 1.23 × 10^4

3. Bool(布尔型)

  • 描述:布尔型(bool)用于表示真值(True 和 False)。它是整型的子类,其中 True 等价于 1False 等价于 0
  • 操作
    • 逻辑运算:and, or, not
    • 比较运算:==, !=, >, <, >=, <=

4. Str(字符串)

  • 描述:字符串(str)用于表示文本数据。字符串是不可变的数据类型,定义时可以使用单引号、双引号或三引号(用于多行字符串)。
  • 操作
    • 字符串拼接:+
    • 字符串重复:*
    • 索引和切片:name[0], name[1:4]
    • 字符串方法:lower(), upper(), replace(), find()
  • # 示例字符串
    s = "Hello, World! Welcome to Python."
    # 1. 获取字符串长度
    length = len(s)
    # 2. 字符串拼接
    s1 = "Hello"
    s2 = "World"
    s3 = s1 + ", " + s2 + "!"
    # 3. 字符串重复
    repeated = s1 * 3
    # 4. 字符串切片
    sub1 = s[0:5]
    sub2 = s[7:]
    sub3 = s[::2]
    # 5. 字符串查找
    position = s.find("World")
    position_index = s.index("World")
    # 6. 字符串替换
    new_s = s.replace("World", "Python")
    # 7. 字符串拆分
    words = s.split()
    comma_split = s.split(",")
    # 8. 字符串连接
    joined_s = " ".join(words)
    # 9. 字符串大小写转换
    upper_s = s.upper()
    lower_s = s.lower()
    capitalized_s = s.capitalize()
    title_s = s.title()
    swapped_s = s.swapcase()
    # 10. 去除空白字符
    stripped_s = s.strip()
    lstripped_s = s.lstrip()
    rstripped_s = s.rstrip()
    # 11. 字符串判断
    starts_with_hello = s.startswith("Hello")
    ends_with_python = s.endswith("Python")
    is_alnum = s1.isalnum()
    is_alpha = s1.isalpha()
    is_digit = s1.isdigit()
    # 12. 字符串格式化
    formatted_s = "My name is {} and I am {} years old.".format("Alice", 25)
    formatted_f_string = f"My name is {'Alice'} and I am {25} years old."
    
    # 打印所有结果
    print(f"Length of the string: {length}")
    print(f"Concatenation: {s3}")
    print(f"Repeated string: {repeated}")
    print(f"Substring [0:5]: {sub1}")
    print(f"Substring [7:]: {sub2}")
    print(f"Substring with step 2: {sub3}")
    print(f"Position of 'World': {position}")
    print(f"Replaced string: {new_s}")
    print(f"Split by space: {words}")
    print(f"Split by comma: {comma_split}")
    print(f"Joined string: {joined_s}")
    print(f"Upper case: {upper_s}")
    print(f"Lower case: {lower_s}")
    print(f"Capitalized: {capitalized_s}")
    print(f"Title case: {title_s}")
    print(f"Swapped case: {swapped_s}")
    print(f"Stripped string: {stripped_s}")
    print(f"Left stripped string: {lstripped_s}")
    print(f"Right stripped string: {rstripped_s}")
    print(f"Starts with 'Hello': {starts_with_hello}")
    print(f"Ends with 'Python': {ends_with_python}")
    print(f"Is alphanumeric: {is_alnum}")
    print(f"Is alphabetic: {is_alpha}")
    print(f"Is digit: {is_digit}")
    print(f"Formatted string: {formatted_s}")
    print(f"Formatted f-string: {formatted_f_string}")
    

5. None(空值)

  • 描述:空值(None)表示没有值或空对象,是一种特殊的常量。在函数中经常用作返回值,表示没有计算结果。
  • 用途
    • 作为默认函数返回值
    • 用于初始化变量以表示尚未赋值

6. List(列表)

  • 描述:列表(list)是有序的、可变的序列,可以包含任意类型的元素。列表可以嵌套,即列表中的元素也可以是列表。
  • 操作
    • 索引和切片:numbers[0], numbers[1:3]
    • 添加元素:append(), insert()
    • 删除元素:remove(), pop(), del
    • 列表方法:sort(), reverse()

7. Tuple(元组)

  • 描述:元组(tuple)是有序的、不可变的序列,可以包含任意类型的元素。元组通常用于需要保护数据不被修改的场景。
  • 操作
    • 索引和切片:coordinates[0], mixed[1:3]
    • 解包(将元组中的元素赋值给多个变量):x, y = coordinates
    • 方法:元组没有像列表那样丰富的方法,但支持基本操作如遍历。

8. Dict(字典)

  • 描述:字典(dict)是键值对的集合,键是唯一的。字典是无序的(Python 3.7+ 版本中为插入顺序)。字典适用于映射关系,如查找表。
  • 操作
    • 访问元素:person["name"]
    • 添加/修改元素:person["age"] = 30
    • 删除元素:del person["city"]
    • 字典方法:keys(), values(), items()
  • 操作描述示例
    创建字典使用花括号 {}dict() 函数创建字典my_dict = {"name": "Alice", "age": 25}
    访问值使用键来访问字典中的值name = my_dict["name"]
    添加/更新项使用键值对来添加新项或更新现有项my_dict["age"] = 26
    删除项使用 del 语句删除特定键及其对应的值del my_dict["age"]
    删除并返回项使用 pop() 方法删除并返回指定键的值value = my_dict.pop("name")
    删除并返回项使用 popitem() 方法删除并返回最后插入的键值对key, value = my_dict.popitem()
    获取值使用 get() 方法获取指定键的值(键不存在时返回默认值)age = my_dict.get("age", "N/A")
    清空字典使用 clear() 方法清空字典my_dict.clear()
    键的视图使用 keys() 方法获取字典的所有键的视图keys = my_dict.keys()
    值的视图使用 values() 方法获取字典的所有值的视图values = my_dict.values()
    项的视图使用 items() 方法获取字典的所有键值对的视图items = my_dict.items()
    更新字典使用 update() 方法将另一个字典的键值对合并到当前字典中my_dict.update({"city": "New York"})
    检查键是否存在使用 in 运算符检查键是否在字典中"name" in my_dict
    获取键的数量使用 len() 函数获取字典中键的数量num_items = len(my_dict)
    # 创建字典
    my_dict = {"name": "Alice", "age": 25}
    # 访问值
    print(my_dict["name"])  # 输出: Alice
    # 添加/更新项
    my_dict["age"] = 26
    my_dict["city"] = "New York"
    # 删除项
    del my_dict["city"]
    # 删除并返回项
    age = my_dict.pop("age")
    print(age)  # 输出: 26
    # 删除并返回项
    key, value = my_dict.popitem()
    print(key, value)  # 输出: name Alice
    # 获取值
    age = my_dict.get("age", "N/A")
    print(age)  # 输出: N/A
    # 清空字典
    my_dict.clear()
    # 键的视图
    my_dict = {"name": "Alice", "age": 25}
    keys = my_dict.keys()
    print(keys)  # 输出: dict_keys(['name', 'age'])
    # 值的视图
    values = my_dict.values()
    print(values)  # 输出: dict_values(['Alice', 25])
    # 项的视图
    items = my_dict.items()
    print(items)  # 输出: dict_items([('name', 'Alice'), ('age', 25)])
    # 更新字典
    my_dict.update({"city": "New York", "country": "USA"})
    # 检查键是否存在
    print("name" in my_dict)  # 输出: True
    # 获取键的数量
    num_items = len(my_dict)
    print(num_items)  # 输出: 3
    

9. Set(集合)

  • 描述:集合(set)是无序的、元素唯一的数据结构。集合用于存储不重复的元素,并支持集合运算(如并集、交集)。
  • 操作
    • 添加元素:add()
    • 删除元素:remove(), discard()
    • 集合运算:交集(&),并集(|),差集(-
  • 常见的算法题用处:
    • 力扣面试150-88题,去重,(当然这道题还是双指针的方法最好了,因为是要原地处理有序数组,保证旁边都是一样的数,这里举个例子如何用集合去重)
    • def remove_duplicates(nums):
          # 创建一个空集合来保存唯一元素
          unique_set = set()
          # 定义一个索引指针,用于将唯一元素放置在 nums 中
          index = 0
          # 遍历 nums 数组
          for num in nums:
              # 如果 num 不在集合中,说明它是一个新的唯一元素
              if num not in unique_set:
                  # 将 num 添加到集合中
                  unique_set.add(num)
                  # 将唯一元素放置到 nums 的当前位置
                  nums[index] = num
                  # 移动索引指针
                  index += 1
          # 返回唯一元素的个数
          return index
      # 示例
      nums = [1, 1, 2, 2, 3, 4, 4, 5]
      length = remove_duplicates(nums)
      # 输出结果
      print("新长度:", length)  # 输出: 新长度: 5
      print("修改后的数组:", nums[:length])  # 输出: 修改后的数组: [1, 2, 3, 4, 5]
      

常用数据类型对比

列表(List) vs 元组(Tuple) vs 集合(Set)vs字典(DICT)
特性列表(List)元组(Tuple)集合(Set)字典(Dict)
定义用方括号 [] 定义用圆括号 () 定义用花括号 {} 定义用花括号 {} 定义,键值对 key: value
可变性可变(可以修改、添加、删除元素)不可变(不能修改、添加、删除元素)可变(可以修改、添加、删除元素)可变(可以修改、添加、删除键值对)
有序性有序(元素顺序保持)有序(元素顺序保持)无序(不保证元素顺序)无序(保持插入顺序)
支持重复支持重复元素支持重复元素不支持重复元素键不支持重复,值支持重复
操作支持丰富的操作:append(), extend(), remove(), pop(), 切片等支持基本操作:切片, 解包等支持集合运算:并集 `,交集 &,差集 -`
性能对于大规模数据,性能较低(因为可变性)性能较高(由于不可变性,通常比列表快)由于哈希表实现,查找操作非常高效查找、插入和删除操作平均时间复杂度为 O(1)
用途适用于需要频繁修改、添加、删除的场景适用于数据不需要修改的场景,例如作为字典的键适用于去重操作和集合运算适用于键值对映射,如存储对象的属性等
示例my_list = [1, 2, 3, 4]my_tuple = (1, 2, 3, 4)my_set = {1, 2, 3}my_dict = {"name": "Alice", "age": 25}

2.常用的数据结构

        顺序表是一种线性数据结构,其元素顺序存储在一块连续的内存空间中。在 Python 中,顺序表通常由列表(list)来实现。顺序表的基本操作包括插入、删除、查找和遍历。顺序表的插入和删除操作包括在表的头部、尾部和任意位置进行插入和删除。查找操作包括遍历查找和二分查找。

1. 数组(Array)——顺序表

  • 定义: 数组是一种线性数据结构,由一组连续的内存位置组成,其中每个元素可以通过索引直接访问。
  • 特点:
    • 元素按顺序存储,支持随机访问。
    • 大小固定(静态数组)。
  • 用法示例:
    # 初始化一个顺序表(列表)
    seq_list = [2, 4, 6, 8]
    # 头插
    seq_list.insert(0, 1)  # 在索引0位置插入元素1
    # 尾插
    seq_list.append(10)  # 在尾部添加元素10
    # 任意位置插入
    seq_list.insert(2, 3)  # 在索引2位置插入元素3
    # 头删
    seq_list.pop(0)  # 删除索引0位置的元素
    # 尾删
    seq_list.pop()  # 删除尾部元素
    # 任意位置删除
    seq_list.pop(2)  # 删除索引2位置的元素
    # 遍历查找
    def linear_search(seq_list, target):
        for i, value in enumerate(seq_list):
            if value == target:
                return i  # 返回目标元素的索引
        return -1  # 如果未找到,返回-1
    index = linear_search(seq_list, 6)
    # 二分查找
    def binary_search(seq_list, target):
        left, right = 0, len(seq_list) - 1
        while left <= right:
            mid = (left + right) // 2
            if seq_list[mid] == target:
                return mid  # 返回目标元素的索引
            elif seq_list[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return -1  # 如果未找到,返回-1
    index = binary_search(seq_list, 6)
    # 打印结果
    print("头插:", seq_list)
    print("尾插:", seq_list)
    print("任意位置插入:", seq_list)
    print("头删:", seq_list)
    print("尾删:", seq_list)
    print("任意位置删除:", seq_list)
    print("遍历查找:", index)
    print("二分查找:", index)
    

2. 链表(Linked List)——顺序表

        链表是一种常用的动态数据结构,适合频繁的插入和删除操作。链表的每个元素称为一个节点,节点包含数据和指向下一个节点的指针。在链表中,元素的插入和删除不需要移动其他元素,但需要调整指针的指向。

        可以使用链表来实现与顺序表(列表)类似的操作,如头插、尾插、任意位置插入、头删、尾删、任意位置删除、遍历查找等。

  • 定义: 链表是一种线性数据结构,其中每个元素称为节点,节点包含数据和指向下一个节点的指针。
  • 特点:
    • 支持动态内存分配。
    • 插入和删除操作在链表中更高效。
  • 用法示例:
    class ListNode:
        def __init__(self, value=0, next=None):
            self.value = value
            self.next = next
    
    # 初始化链表为空
    head = None
    

    这里遇到最多的算法题反转链表,力扣面试150-92反转链表,

    • 步骤解析(这个题与普通反转列表的区别就是普通的全部都反转了无需考虑前后点,这个也只是多了一步确认从哪开始反转)
    • 定位反转的起点:通过遍历链表,找到位置 left 的节点,即反转部分的起点。这个节点的前一个节点我们称为 prev

    • 反转指定区间的节点:使用三个指针进行反转操作,分别是 prev(当前节点的前一个节点),current(当前节点),以及 next(当前节点的下一个节点)。

    • 连接反转后的部分:将反转后的部分连接回原链表。prev 指向反转后的头节点,反转区间的末尾节点连接到 right 位置后的第一个节点。

    • class ListNode:
          def __init__(self, value=0, next=None):
              self.value = value
              self.next = next
      
      def reverse_between(head, left, right):
          if not head or left == right:
              return head
          
          # 创建一个x,方便处理头节点为left的情况
          x = ListNode(0)
          x.next = head
          prev = x
          
          #移动 prev 到 left 的前一个节点
          for _ in range(left - 1):
              prev = prev.next
          
          #开始反转
          y = prev.next
          next = None
          
          for _ in range(right - left):
              next = y.next 
              #将 y 节点的下一个节点存储在 next 中。next 变量保存了即将被反转的节点。
      
              y.next = next.next
              #设置为 next.next,即跳过 next 节点,
              #使 y 节点直接连接到 next 节点的下一个节点。将 next 从当前链表中拆出来。
      
              next.next = prev.next
              #将 next 节点的下一个指针 next.next 指向 prev.next,即链表中反转部分的当前头部。
              #这样,next 节点就成为了反转部分的新头部。
      
              prev.next = next
              #更新 prev.next 指向新的头部 next,即反转后的链表部分。
              #prev 节点的 next 就连接到了新的头节点上,完成了反转。
      
          return dummy.next
      

3. 栈(Stack)

  • 定义: 栈是一种线性数据结构,遵循后进先出(LIFO)的原则。
  • 特点:
    • 插入和删除操作只能在栈顶进行。
    • 用于处理逆序问题(如括号匹配、逆波兰表达式计算)。
  • 用法示例:力扣面试150-20有效的括号(注意这道题出现在两次面试中,不得不说力扣这个刷题的确实很管用)

class Solution:
    def isValid(self, s: str) -> bool:
        dic = {'{': '}',  '[': ']', '(': ')', '?': '?'}
        #这里用字典匹配后续的括号,前后括号
        stack = ['?']
        #到时候如果最后只剩下?了证明就是对滴
        for c in s:
            if c in dic: 
                stack.append(c)
            elif dic[stack.pop()] != c: 
                return False 
        return len(stack) == 1

 

4. 队列(Queue)

  • 定义: 队列是一种线性数据结构,遵循先进先出(FIFO)的原则。
  • 特点:
    • 插入操作发生在队尾,删除操作发生在队首。
    • 常用于任务调度和缓冲区管理。
  • 用法示例:
  • 队列先进先出的原则可以使用在归并排序中:例如面试150-23题目
    

本题目可以使用最小堆(优先级队列)来合并链表。(这个题目是个困难题,印象中好像某个大厂出现过原题,我当时写的啥也不是,这题目我需要再斟酌,有大佬有更好的思路拜托大佬们评论区指导我一下谢谢谢谢!)

5. 树(Tree)

  • 定义: 树是一种非线性数据结构,由节点组成,通常具有层次结构。每个节点包含数据,并可以有零个或多个子节点。
  • 特点:
    • 特殊的树结构如二叉树、二叉搜索树、AVL 树等。
    • 常用于表示层次关系(如文件系统、组织结构)。
  • 用法示例:树真的超级常用递归,完全可以在树的这里好好学习一番递归函数,因为他的性质很合适
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root: 
            return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

 还有就是二叉树的各种遍历,需要跟排序算法一样了如指掌,实在不会背过都可以(开玩笑的哈哈),以这个为延申可以做很多题目。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def preorder_traversal(root):#前序遍历
    if root is None:
        return []
    # 访问根节点
    result = [root.val]
    # 递归遍历左子树
    result += preorder_traversal(root.left)
    # 递归遍历右子树
    result += preorder_traversal(root.right)
    return result

def inorder_traversal(root): #中序遍历
    if root is None:
        return []
    # 递归遍历左子树
    result = inorder_traversal(root.left)
    # 访问根节点
    result.append(root.val)
    # 递归遍历右子树
    result += inorder_traversal(root.right)
    return result

def postorder_traversal(root):#后续遍历
    if root is None:
        return []
    # 递归遍历左子树
    result = postorder_traversal(root.left)
    # 递归遍历右子树
    result += postorder_traversal(root.right)
    # 访问根节点
    result.append(root.val)
    return result

6. 图(Graph)

  • 定义: 图是一种非线性数据结构,由顶点和边组成。顶点通过边相互连接。
  • 特点:
    • 图可以是有向图或无向图,有权图或无权图。
    • 常用于网络路由、社交网络分析等。
  • 用法示例:
     

7. 堆(Heap)

  • 定义: 堆是一种特殊的树形数据结构,满足堆属性。最大堆中每个节点的值都大于或等于其子节点的值,最小堆中每个节点的值都小于或等于其子节点的值。
  • 特点:
    • 常用于实现优先队列。
    • 支持快速获取最大值或最小值。
  • 用法示例:堆排序谁懂!超级容易出现的面试题目,冲冲冲!
 

8. 散列表(Hash Table)

  • 定义: 散列表是一种数据结构,通过将键映射到值来实现键值对的存储。它使用哈希函数将键映射到数组中的特定位置。
  • 特点:
    • 支持快速的查找、插入和删除操作。
    • Python 中的字典(dict)实现了散列表。

3.常用的关键字集锦

关键字作用使用场景补充说明
and逻辑与用于两个条件都为真时,结果为真可用于条件组合
or逻辑或两个条件中只要一个为真,结果为真可用于条件组合
not逻辑非将布尔值取反可用于布尔值判断
if条件判断条件为真时执行代码块常与 elseelif 结合
elif额外条件if 条件不满足时的额外判断通常跟在 if 之后
else备用方案ifelif 条件不满足时执行用于条件语句和异常处理
for循环遍历序列或可迭代对象常与 range() 结合使用
while循环当条件为真时,重复执行代码块适合未知循环次数的场景
continue跳过当前循环跳过当前循环的剩余部分,进入下一次循环主要用于循环控制
break终止循环立即终止当前循环适合提前结束循环
pass占位符什么也不做,用于占位用于未实现的代码块
try异常捕获用于捕获可能出现的异常常与 exceptfinally 结合
except异常处理在捕获异常后执行的代码块用于处理异常
finally异常清理无论是否有异常,都会执行常用于资源清理
raise抛出异常主动引发一个异常可自定义异常类型
import导入模块导入外部模块或库常与 from 结合
def定义函数定义一个函数或方法函数体内使用 return 返回值
return返回值从函数中返回一个值并结束函数用于结束函数的执行
class定义类定义一个类类定义中包含属性和方法
lambda匿名函数定义一个简短的匿名函数通常用于简单函数表达式
global声明全局变量声明一个变量为全局变量用于函数内部修改全局变量
nonlocal声明非局部变量用于嵌套函数中,声明外层函数的变量修改闭包作用域中的变量
in成员判断检查一个值是否在序列或集合中常用于 if 语句
is身份判断判断两个对象是否为同一个对象比较对象的内存地址
None空值表示什么都没有NoneType 的实例
assert断言用于调试条件为 False 时触发异常
with上下文管理简化资源管理常与 open 一起使用
yield生成器定义一个生成器函数函数会暂停并返回值

4.常用的函数列举

函数作用使用场景补充说明
next()获取迭代器的下一个元素手动遍历迭代器如果没有更多元素,会抛出 StopIteration 异常
len()返回对象的长度计算序列或集合的元素数量常用于 strlisttuple
range()返回一个范围对象生成一个数字序列通常用于循环
enumerate()返回枚举对象在循环中获取索引和值常用于 for 循环
zip()打包可迭代对象将多个序列打包成元组的迭代器用于并行遍历
map()函数映射将函数应用于可迭代对象的每个元素返回一个迭代器
filter()过滤元素根据条件筛选可迭代对象的元素返回满足条件的元素
sorted()返回排序后的列表对序列进行排序不修改原序列,返回新的列表
min()返回最小值查找序列或集合中的最小元素适用于 strlist
max()返回最大值查找序列或集合中的最大元素适用于 strlist
sum()计算总和求序列或集合中元素的总和仅适用于数字类型
abs()绝对值计算数字的绝对值返回非负数
all()全真判断判断可迭代对象的所有元素是否为真如果全为真,返回 True
any()存在真判断判断可迭代对象中是否有任意一个元素为真如果有一个为真,返回 True
type()返回对象类型获取对象的类型常用于检查对象类型
isinstance()检查实例判断对象是否为特定类的实例用于类型判断
id()返回对象唯一标识获取对象的内存地址常用于比较对象身份

注意其中next面试的时候被问到,我回答的不太靠谱,这里涉及到迭代器和生成器的原理,我在这里补充一下:

5.迭代器和生成器

1. 迭代器原理

迭代器(Iterator)是一种用于遍历数据结构中元素的设计模式,能够按照顺序访问容器中的每个元素,而不需要了解容器的底层实现。迭代器提供了一种统一的接口来访问容器中的元素。

迭代器的核心特征

  • 封装:迭代器封装了数据的遍历过程,不需要暴露容器的内部结构。
  • 状态保存:迭代器能够在遍历过程中保存状态,以便在需要时恢复。

实现原理

  • 迭代器协议:在 Python 中,迭代器需要实现两个关键方法:
    • __iter__():返回迭代器对象自身,通常可以直接返回 self
    • __next__():返回容器中的下一个元素。如果没有更多元素可以返回,则抛出 StopIteration 异常,表示迭代已结束。

2. Python 中的迭代器与可迭代对象

在 Python 中,有两种重要的概念:

  • 可迭代对象(Iterable):指那些可以返回迭代器的对象,如列表、元组、字典、集合、字符串等。可迭代对象实现了 __iter__() 方法,但不一定实现 __next__() 方法。
  • 迭代器(Iterator):指那些实现了 __iter__()__next__() 方法的对象。迭代器不仅是可迭代对象,还可以通过 next() 函数获取下一个元素。
  • 迭代器(iterator)一定是可迭代对象(iterable),可迭代对象不一定是迭代器

可迭代对象

  • 列表 (list)
  • 元组 (tuple)
  • 字典 (dict)
  • 集合 (set)
  • 字符串 (str)

迭代器

  • 生成器(使用 yield 的函数)
  • 自定义的迭代器类(如上述示例)
特性列表 (List)迭代器 (Iterator)生成器 (Generator)
定义有序的元素集合,可变的容器类型实现了 __iter__()__next__() 方法的对象使用 yield 关键字创建的特殊迭代器
创建使用方括号创建,如 [1, 2, 3]使用 iter() 函数创建,如 iter(lst)使用生成器函数创建,如 def gen(): yield ...
存储方式存储所有元素在内存中按需生成元素,不需一次性存储所有元素按需生成元素,不需一次性存储所有元素
访问方式支持随机访问,如 lst[0]只能逐个访问,通过 next() 函数只能逐个访问,通过 next() 函数
内存使用存储所有元素,占用更多内存节省内存,按需生成元素节省内存,按需生成元素
迭代功能可以被 for 循环遍历可以被 for 循环遍历可以被 for 循环遍历
重复使用可以多次遍历遍历一次后不能重用,需要重新创建遍历一次后不能重用,需要重新创建
性能遍历速度快,但内存消耗大性能较好,但每次调用 next() 可能略慢性能较好,特别适合处理大数据
示例lst = [1, 2, 3]it = iter([1, 2, 3])def gen(): yield 1; yield 2; yield 3

3. 生成器原理

生成器(Generator)是 Python 中一种特殊的迭代器,用于按需生成值。与一次性创建所有元素的数据结构(如列表或元组)不同,生成器每次迭代时只生成下一个值,因此更节省内存并支持无限序列或大量数据流的操作。

2. 生成器的关键特性
  • 延迟计算:生成器不会一次性计算所有结果,而是每次需要时逐步计算并生成值。这种按需计算的方式可以节省内存。
  • 状态保持:生成器在每次 yield 语句执行后会保存其执行状态,下一次调用时会从上次暂停的地方继续执行。
  • 内存效率:生成器在生成值时只需存储当前状态,相比于列表或元组,内存消耗较小。
3. yield 关键字
  • 定义生成器函数yield 关键字用于定义生成器函数。生成器函数是一种特殊的函数,当执行到 yield 语句时,函数的执行会暂停,并返回 yield 后面的值。函数的状态会被保存,每次迭代时从上次暂停的地方继续执行。

以下代码创造一个生成器

def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

counter = count_up_to(5)
for num in counter:
    print(num)

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值