Python 面试必知必会(一):数据结构

《Python Cookbook》的作者David Beazley的课程PPT开源了,目标用户是希望从编写基础脚本过渡到编写更复杂程序的高级 Python 程序员,课程主题侧重于流行库和框架中使用的编程技术,主要目的是更好地理解 Python 语言本身,以便阅读他人的代码,并将新发现的知识应用到自己的项目中。内容组织的很棒,总共分为九个章节,我在阅读过程中顺便翻译整理下,用来查缺补漏了。翻译内容并非原版无对照翻译,有所增减,第一节内容是快速过了下Python基础知识,我这里直接跳过从第二节开始。更多硬核内容可以移步 LLM应用全栈开发

感兴趣可前往原课件进行阅读👉 https://github.com/dabeaz-course/python-mastery/blob/main/PythonMastery.pdf

数据结构

真正的程序必须处理复杂的数据,这里以持有股票为例探索了如何为对象选择合适的数据结构。100 shares of GOOG at $490.10

  • 元组表示

    • s = (‘GOOG’, 100, 490.1)

    • 可以像数组一样使用:name = s[0]

    • Unpacking并分配给单独的变量:name, shares, price = s

    • 不可变:s[1] = 75 # TypeError. No item assignment

  • 字典表示

    • s = {'name' : 'GOOG','shares' : 100,'price' : 490.1
      }
      
    • 使用键访问:name = s[‘name’]

    • 允许修改:s[‘shares’] = 75,s[‘date’] = '7/25/2015‘,del s[‘name’]

  • 自定义类

    • class Stock:def __init__(self, name, shares, price):self.name = nameself.shares = sharesself.price = price
      
    • 使用对象进行操作

      >>> s = Stock('GOOG', 100, 490.1)
      >>> s.name
      'GOOG'
      >>> s.shares * s.price
      49010.0
      >>>
      
  • 类的变体

    • Slots(插槽)

      插槽是一种用于定义类的特殊属性,它可以用来限制实例的属性。通过使用插槽,你可以显式地指定一个类的实例应具有哪些属性,从而节省内存空间。当你定义了插槽时,每个实例只会为插槽中的属性分配内存,而不会为其他属性分配内存,这对于大量实例化的类或具有大量属性的类来说,可以显著减少内存消耗。

      class Stock:__slots__ = ('name', 'shares', 'price')def __init__(self, name, shares, price):self.name = nameself.shares = sharesself.price = price
      
    • Dataclasses(数据类)

      数据类是Python 3.7及更高版本中的一个装饰器,用于简化创建带有属性的类的过程。

      通过在类定义上添加@dataclass装饰器,你可以自动获得一些常见的方法,如__init____repr____eq__等,而无需显式编写这些方法。数据类还提供了一种简洁的语法来定义属性,并可以自动生成属性的默认值和类型注解。这样可以减少编写样板代码的工作量,并使类定义更加简洁和易读。

      from dataclasses import dataclass
      @dataclass
      class Stock:name : strshares : intprice: float
      
    • Named Tuples(命名元组)

      命名元组是一种具有命名字段的不可变(immutable)的数据结构,类似于元组(tuple)和字典(dictionary)的结合体。与普通的元组不同,命名元组的每个字段都有一个名称,可以通过名称进行访问,而不仅仅是通过索引。命名元组的字段是不可变的,这意味着一旦创建了命名元组的实例,就不能修改其字段的值。命名元组具有类似元组的性质,可以进行Unpacking操作、迭代和比较,但是字段的名称提供了更好的可读性和代码的自文档性。命名元组适用于表示简单的数据记录,其中字段的值不会发生变化。

      import typing
      class Stock(typing.NamedTuple):name: strshares: intprice: float
      
      >>> s = Stock('GOOG', 100, 490.1)
      >>> s[0]
      'GOOG'
      >>> name, shares, price = s
      >>> print('%10s %10d %10.2f' % s)
      GOOG 100 490.10
      >>> isinstance(s, tuple)
      True
      >>> s.name = 'ACME'
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      AttributeError: can't set attribute
      >>>
      

容器

  • 列表

    • 当数据顺序很重要时使用列表

    • 元组列表

      portfolio = [
      ('GOOG', 100, 490.1),
      ('IBM', 50, 91.1),
      ('CAT', 150, 83.44)
      ]
      portfolio[0] ->('GOOG', 100, 490.1)
      portfolio[1] ->('IBM', 50, 91.1)
      
    • 列表可以排序和重新排列

  • 集合

    • 集合是唯一项的无序集合

    • 集合消除重复

      names = ['IBM''YHOO''IBM''CAT''MSFT''CAT''IBM'] unique_names = set(names)
      
    • 集合对于成员资格测试很有用

      members = set()
      members.add(item) # Add an item
      members.remove(item) # Remove an item
      if item in members: # Test for membership
      ...
      
  • 字典(无序键值数据)

    • 适用于索引和查找表

    • 将元组用于字典键

      prices = {('ACME','2017-01-01') : 513.25,('ACME','2017-01-02') : 512.10,('ACME','2017-01-03') : 512.85,('SPAM','2017-01-01') : 42.1,('SPAM','2017-01-02') : 42.34,('SPAM','2017-01-03') : 42.87,
      }
      
  • 常用操作示例etc,略过

collections 模块

提供常见数据结构的一些变体(对专业问题很有用)

  • defaultdict

    defaultdict 是 Python 标准库 collections 模块中的一个类,它是一个字典(dict)的子类,具有与普通字典相同的功能,但是在访问不存在的键值时,不会抛出 KeyError 异常,而是返回指定的默认值。

    defaultdict 接受一个参数 default_factory,它可以是一个函数、一个lambda表达式或一个类对象,用来指定默认值的类型。当访问一个不存在的键值时,如果存在 default_factory,则会调用它并返回其结果,如果不存在,则返回默认值类型的默认值。

    >>> from collections import defaultdict
    >>> d = defaultdict(list)
    >>> d
    defaultdict(<class 'list'>, {})
    >>> d['x']
    []
    >>> d
    defaultdict(<class 'list'>, {'x': []})
    
  • Counter

    Counter是Python标准库collections模块中的一个类,使用Counter可以方便地统计可迭代对象(如列表、元组、字符串)中各个元素的出现次数。下面是Counter类的一些常用方法和示例用法:

    1. 创建一个Counter对象:
    from collections import Countermy_list = [1, 2, 3, 2, 1, 3, 2, 1]
    my_counter = Counter(my_list)
    
    1. 访问元素的计数:
    print(my_counter[1])  # 输出 3,元素1出现了3次
    print(my_counter[4])  # 输出 0,元素4未出现
    
    1. 统计字符串中字符的出现次数:
    my_string = "Hello, World!"
    string_counter = Counter(my_string)
    print(string_counter['l'])  # 输出 3,字母'l'出现了3次
    
    1. 统计可迭代对象中各元素的计数:
    my_list = [1, 2, 3, 2, 1, 3, 2, 1]
    my_counter = Counter(my_list)
    print(my_counter)  # 输出 Counter({1: 3, 2: 3, 3: 2})
    
    1. 获取出现次数最多的元素:
    print(my_counter.most_common(2))  # 输出 [(1, 3), (2, 3)],出现次数最多的两个元素及其计数
    
    • deque

      deque是双端队列(double-ended queue)的缩写。deque可以在两端进行高效的插入和删除操作,因此它非常适用于需要频繁在两端进行操作的场景,与列表(list)相比,deque在插入和删除元素时的性能更好,特别是当元素数量很大时。deque对象支持一系列方法,例如:

      append(x): 在队列的右侧添加元素x。
      appendleft(x): 在队列的左侧添加元素x。
      pop(): 移除并返回队列的最右侧的元素。
      popleft(): 移除并返回队列的最左侧的元素。
      extend(iterable): 在队列的右侧添加可迭代对象iterable中的元素。
      extendleft(iterable): 在队列的左侧添加可迭代对象iterable中的元素。
      
    1. 保留最近 N 件事的历史记录

      from collections import deque
      history = deque(maxlen=N)
      with open(filename) as f:for line in f:history.append(line)...
      

迭代

  • 带Unpacking的迭代

    portfolio = [('GOOG', 100, 490.1),('IBM', 50, 91.1),('CAT', 150, 83.44),('IBM', 100, 45.23),('GOOG', 75, 572.45),('AA', 50, 23.15)]
    for name, shares, price in portfolio:...
    
  • 考虑不同大小的数据结构列表,通配符Unpacking(仅限 Python 3)

    prices = [['GOOG', 490.1, 485.25, 487.5 ],['IBM', 91.5],['HPE', 13.75, 12.1, 13.25, 14.2, 13.5 ],['CAT', 52.5, 51.2]
    ]
    for name, *values in prices:print(name, values)
    
  • zip并行迭代多个序列

    columns = ['name','shares','price']
    values = ['GOOG',100, 490.1 ]
    for colname, val in zip(columns, values):
    
  • enumerate遍历一个可迭代对象并同时获取索引 n 和对应的元素 name

    names = ["Alice", "Bob", "Charlie"]
    for n, name in enumerate(names):print(f"Index: {n}, Name: {name}")
    
  • Sequence Reductions

    最大,最小,求和

    >>> s = [1, 2, 3, 4]
    >>> sum(s)
    10
    >>> min(s)
    1
    >>> max(s)
    4
    >>>
    

    布尔测试

    >>> s = [False, True, True, False]
    >>> any(s)
    True
    >>> all(s)
    False
    >>>
    
  • Unpacking可迭代对象

    a = (1, 2, 3)
    b = [4, 5]
    c = [ *a, *b ] # c = [1, 2, 3, 4, 5] (list)
    d = ( *a, *b ) # d = (1, 2, 3, 4, 5) (tuple)
    
  • Unpacking字典

    a = { 'name': 'GOOG', 'shares': 100, 'price':490.1 }
    b = { 'date': '6/11/2007', 'time': '9:45am' }
    c = { **a, **b }
    >>> c
    { 'name': 'GOOG', 'shares':100, 'price': 490.1,
    'date': '6/11/2007,'time': '9:45am' }
    >>>
    
  • 参数传递

    • 可迭代对象可以展开为位置参数

      a = (1, 2, 3)
      b = (4, 5)
      func(*a, *b) # func(1,2,3,4,5)
      
    • 词典可以展开到关键字参数

      c = {'x': 1, 'y': 2 }
      func(**c) func(x=1, y=2)
      
  • 生成器表达式

    列表推导的一种变体,通过迭代生成结果。一个生成器只能被遍历一次

    >>> nums = [1,2,3,4]
    >>> squares = (x*x for x in nums)
    >>> for n in squares:print(n, end=' ')
    1 4 9 16
    >>> for n in squares:print(n, end=' ')
    >>>
    

    生成器在结果是一个中间步骤的情况下非常有用

    def process_data(data):for item in data:# 执行一些处理操作processed_item = item * 2yield processed_item# 生成器作为中间步骤
    intermediate_result = process_data([1, 2, 3, 4, 5])# 在中间结果上继续操作
    final_result = sum(intermediate_result)print(final_result)  # 输出:30
    

Python 内置特性

什么是内置?属于 Python 解释器一部分的对象,通常完全用 C 语言实现,从某种意义上说,您可以在程序中使用的最原始的对象。

引擎盖下

所有对象都有一个 id(内存地址)、类(type类型)和一个引用计数(用于垃圾回收)

image-20230808182601347

内置操作

内置类型根据预定义的 “协议”(特殊方法)运行

>>> a = 2
>>> b = 3
>>> a + b
5
>>> a.__add__(b) # Protocol
5
>>> c = 'hello'
>>> len(c)
5
>>> c.__len__() # Protocol
5
>>>

对象协议被嵌入到解释器的非常低层(字节码)中

image-20230808201223801

扩展Python的内置功能,并根据特定的领域或需求创建出行为类似于内置对象的新对象。

Python的fractions模块允许你创建和操作分数对象;Decimal模块提供了高精度的十进制运算,Decimal对象可以像内置的整数和浮点数一样进行操作,但它的运算结果更准确。

>>> from fractions import Fraction
>>> a = Fraction(2, 3)
>>> b = Fraction(1, 2)
>>> a + b
Fraction(7, 6)
>>> a > 0.5
True
>>>

Container Representation

容器(可以是数组、列表、集合、字典等数据结构,它们可以存储和管理多个元素)的表示方式通常包括容器的内部结构、访问元素的方法、迭代元素的方式以及对容器进行添加、删除、搜索等操作的接口。

  • 容器对象仅保存对其存储值的引用(指针)

    image-20230808203030316

  • 涉及容器内部的所有操作仅操作指针(而不是对象)

  • 所有可变容器(列表、字典、集合)都倾向于过度分配内存,以便始终有一些可用插槽可用,这是一种性能上的优化方式,额外的空间意味着大多数追加和插入操作都非常快(空间已经可用,不需要内存分配)
    img-1R83h8dL-1691502493607]

  • 根据存储的值的数量增长,容器所占用的内存也相应增加,具体如下:

    • 列表的内存使用量在满时约增加12.5%。
    • 集合的内存使用量在 2/3 满时增加4倍。
    • 字典的内存使用量在 2/3 满时增加2倍

集合/字典哈希

  • 集合和字典基于哈希

  • 键用于确定“哈希值”(__ hash__ () 方法)

    a = 'Python'
    b = 'Guido'
    c = 'Dave'
    >>> a.__hash__()
    -539294296
    >>> b.__hash__()
    1034194775
    >>> c.__hash__()
    2135385778
    
  • 仅限于使用“可哈希”对象(字符串、数字或元组)设置/字典键

    >>> a = {'IBM','AA','AAPL'}
    >>> b = {[1,2],[3,4]}
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'list'
    
  • 哈希图示

    image-20230808204944680

  • 解决哈希碰撞,最终会尝试每个slot

容器协议

>>> a = ['x','y','z']
>>> a[1]
'y'
>>> a.__getitem__(1) # Protocol
'y'
>>> 'z' in a
True
>>> a.__contains__('z') # Protocol
True

新容器:可以通过实现所需的方法来创建自定义容器对象

Mapping, MutableMapping
Sequence, MutableSequence
Set, MutableSetclass MyContainer(collections.abc.MutableMapping):...

赋值操作详解

赋值操作实际上是将一个变量与一个值关联起来。当我们执行赋值操作时,变量只是引用了内存中存储值的位置,而不是对值本身进行复制。

  • 对于可变的数据类型,赋值操作会直接修改对象的值,而不会创建新的对象。
a = [1,2,3]
b = a
c = [a,b]
>>> a.append(999)
>>> a
[1,2,3,999]
>>> b
[1,2,3,999]
>>> c
[[1,2,3,999], [1,2,3,999]]
>>>
  • 对于不可变的数据类型,赋值操作实际上会创建一个新的对象,并将变量与该新对象关联起来。这是因为不可变对象的值无法更改,所以在修改时需要创建一个新的对象。
  • 列表的浅copy与深copy话题

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

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

相关文章

【深度学习】采用自动编码器生成新图像

一、说明 你知道什么会很酷吗&#xff1f;如果我们不需要所有这些标记的数据来训练 我们的模型。我的意思是标记和分类数据需要太多的工作。 不幸的是&#xff0c;大多数现有模型从支持向量机到卷积神经网&#xff0c;没有它们&#xff0c;卷积神经网络就无法训练。无监督学习不…

中断子系统--硬件层(GICv3)

目录 综述 硬件层--GICV3 中断类型 中断状态 Distributor组件 中断使能配置 中断触发方式配置 中断优先级配置  中断分组标记 GIC处理中断流程 综述 由上面的block图&#xff0c;我们可知linux kernel的中断子系统分成4个部分&#xff1a; 硬件层&#xff1a;最下层…

AP2400 LED汽车摩灯照明电源驱动 过EMC DC-DC降压恒流IC

产品特点 宽输入电压范围&#xff1a;5V&#xff5e;100V 可设定电流范围&#xff1a;10mA&#xff5e;6000mA 固定工作频率&#xff1a;150KHZ 内置抖频电路&#xff0c;降低对其他设备的 EMI干扰 平均电流模式采样&#xff0c;恒流精度更高 0-100%占空比控制&#xff0…

连续四年入选!三项荣耀!博云科技强势上榜Gartner ICT技术成熟度曲线

日&#xff0c;全球知名咨询公司Gartner发布了2023年度的《中国ICT技术成熟度曲线》&#xff08;《Hype Cycle for ICT in China, 2023》&#xff0c;以下简称“报告”&#xff09;。令人瞩目的是&#xff0c;博云科技在报告中荣获三项殊荣&#xff0c;入选云原生计算&#xff…

揭秘bi数据分析系统:如何轻松掌握商业智能的秘密

在大数据时代的背景下&#xff0c;企业开始越来越重视数据分析的重要性。bi数据分析系统不仅可以帮助企业感知市场变化趋势&#xff0c;还可以实时监测并评估企业经营决策的效果&#xff0c;支持企业的持续发展。在国内&#xff0c;国产数据处理工具如瓴羊Quick BI等崛起&#…

Neety与IO模型简介

Netty与IO模型简介 1、Netty 是由 JBOSS 提供的一个 Java 开源框架&#xff0c;现为 Github 上的独立项目。 2、Netty 是一个异步的、基于事件驱动的网络应用框架&#xff0c;用以快速开发高性能、高可靠性的网络 IO 程序。 3、Netty 主要针对在 TCP 协议下&#xff0c;面向…

【android】mac mini m2安装android studio

文章目录 一、环境搭建1.1 安装路径1.2 mac arm1.3 安装android studio 二、安装sdk三、更新sdk3.1 关闭代理3.2 重新更新sdk 四、更新api五、项目创建六、gradle安装七、avd八、问题&#xff1a;build tools缺失九、编译运行小结 一、环境搭建 1.1 安装路径 windows&#xf…

高温老化房软件使用教程

高温老化炉软件通常具有以下几个模块&#xff1a; 1. 参数设置模块&#xff1a;该模块用于设置高温老化炉的相关参数&#xff0c;包括温度、时间、压力等。用户可以通过输入框、滑动条或下拉菜单等方式设定参数&#xff0c;并将参数发送给高温老化炉。 2. 监控模块&#xff1a;…

Ansible环境搭建,CentOS 系列操作系统搭建Ansible集群环境

Ansible是一种自动化工具&#xff0c;基于Python写的&#xff0c;原理什么的就不过多再说了&#xff0c;详情参考&#xff1a;https://www.itwk.cc/post/403.html https://blog.csdn.net/qq_34185638/article/details/131079320?spm1001.2014.3001.5502 环境准备 HOSTNAMEIP…

CAD绘制法兰、添加光源、材质并渲染

首先绘制两个圆柱体&#xff0c;相互嵌套 在顶部继续绘制圆柱体&#xff0c;这是之后要挖掉的部分 在中央位置绘制正方形 用圆角工具&#xff1a; 将矩形的四个角分别处理&#xff0c;效果&#xff1a; 用拉伸工具 向上拉伸到和之前绘制的圆柱体高度齐平 绘制一个圆柱体&#…

VUE框架:vue2转vue3全面细节总结(2)导航守卫

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人_python人工智能视觉&#xff08;opencv&#xff09;从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了&#xff1a; https://blog.csdn.net/lbcy…

laravel项目运行问题记录

一.首页404未找到 检查项目配置是否配置好 解决地址:phpstudy网站或站点创建成功,打开无响应_php打开提示站点创建成功_荒-漠的博客-CSDN博客 二.vendor目录不存在 composer未安装 解决地址:laravel安装composer依赖_荒-漠的博客-CSDN博客 三.首页可以展示 里面路径404 未配…

Adobe ColdFusion 反序列化漏洞复现(CVE-2023-29300)

0x01 产品简介 Adobe ColdFusion是美国奥多比&#xff08;Adobe&#xff09;公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞&#xff0c;该漏洞源于受到不受信任数据反序列化漏洞的影响&#xff0c;攻击…

C# App.config和Web.config加密

步骤1&#xff1a;创建加密命令 使用ASP.NET提供的命令工具aspnet_regiis来创建加密命令。 1、打开控制台窗口&#xff0c;在命令行中输入以下命令&#xff1a; cd C:\Windows\Microsoft.NET\Framework\v4.xxxxx aspnet_regiis.exe -pef connectionStrings "C:\MyAppFo…

C#,OpenCV开发指南(01)

C#&#xff0c;OpenCV开发指南&#xff08;01&#xff09; 一、OpenCV的安装1、需要安装两个拓展包&#xff1a;OpenCvSharp4和OpenCvSharp4.runtime.win 二、C#使用OpenCV的一些代码1、需要加头文件2、读取图片3、在图片上画矩形框4、 在图片上画直线 一、OpenCV的安装 1、需…

南京https证书中的通配符https证书

随着互联网的快速发展&#xff0c;越来越多的网站开始使用HTTPS协议来保证用户的信息安全和隐私。而HTTPS协议的实现离不开HTTPS证书的支持。HTTPS证书是一种数字证书&#xff0c;用于验证网站的身份并加密数据传输。它通过使用公钥加密技术&#xff0c;确保用户与网站之间的通…

[JAVAee]网络编程-套接字Socket

目录 基本概念 发送端与接收端 请求与响应 ​编辑客户端与服务器 Socket套接字 分类 数据报套接字 流套接字传输模型 UDP数据报套接字编程 DatagramSocket API DatagramPacket API InetSocketAddress API 示例一: 示例二: TCP流数据报套接字编程 ServerSock…

LISA:通过大语言模型进行推理分割

论文&#xff1a;https://arxiv.org/pdf/2308.00692 代码&#xff1a;GitHub - dvlab-research/LISA 摘要 尽管感知系统近年来取得了显著的进步&#xff0c;但在执行视觉识别任务之前&#xff0c;它们仍然依赖于明确的人类指令来识别目标物体或类别。这样的系统缺乏主动推理…

在golang中引入私有git仓库的pkg包?引入私有Git仓库的包:在Go语言项目中轻松实现

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to Golang Language.✨✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(37)-掌握Fiddler中Fiddler Script用法你有多牛逼-下

1.简介 Fiddler是一款强大的HTTP抓包工具&#xff0c;它能记录所有客户端和服务器的http和https请求&#xff0c;允许你监视&#xff0c;设置断点&#xff0c;甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说&#xff0c;都有很大的帮助。Fiddler提供的功能基本上能…