Python之序列

2023-11-04

        序列是一种数据存储方式,用来存储一系列的数据。在内存中,序列就是一块用来存放多个值的连续空间。比如一个整数序列:[10,20,30,40]。可以这样表示:

        由于Python3中一切皆对象,在内存中实际是按照如下方式储存的:

        a=[10,20,30,40]

        从图示中我们可以看出,序列中存储的是整数对象的地址,而不是整数对象的值。

        Python3常用的序列对象有:

        字符串、元组、列表、字典、集合

列表简介

        列表:用于存储任意数目、任意类型的数据集合。

        列表是内置可变序列,包含多个元素的有序连续的内存空间。

        列表的标准语法格式:a=[10,20,30,40]

        其中,10,20,30,40这些称为:列表a的元素。

        列表中的元素可以各不相同,可以是任意类型。比如:a=[10,'20','abc',True]

        列表对象常用方法如下:

方法 要点 描述
list.append(x) 增加元素 将元素x增加到列表list尾部
list.extend(alist) 增加元素 将列表alist所有元素加到列表list尾部
list.insert(index,x) 增加元素 将列表list指定位置index处插入元素
list.remove(x) 删除元素 将列表list中删除首次出现的指定元素x,若不存在该元素则抛出异常
list.pop([index]) 删除元素 删除并返回列表list指定为止index处的元素,默认是最后一个元素
list.clear() 删除所有元素 删除列表list中所有元素,并不是删除该列表对象
list.index(x) 访问元素 返回第一个x在列表list的索引位置,若不存在x元素抛出异常
list.count(x) 计数 返回指定元素x在列表list中出现的次数
len(list) 列表长度 返回列表list中包含元素的个数
list.reserse() 翻转列表 所有元素原地翻转
list.sort() 排序 所有元素原地排序
list.copy() 浅拷贝 返回列表对象的浅拷贝

         Python的列表大小可变,根据需要随时增加或缩小。

        字符串和列表都是序列类型,一个字符串是一个字符序列,一个列表是任何元素的序列。在字符串中的很多方法,在列表中也有类似的用法,几乎一模一样。

列表的创建

基本[]创建

 list()创建

        使用list()可以将任何可迭代的数据类型装换为列表。

range()创建整数列表 

        range()可以帮助我们非常方便的创建整数列表,这个在开发中极具作用。语法格式为:

        range([start,] end [,step])

        start参数:可选,表示起始数字。默认是0

        end参数:必选,表示结尾数字(不包括该数字,左闭右开)

        step参数:可选,表示步长,默认为1

        Python3中range()返回的是一个range对象,而不是列表。我们需要通过list()方法将其转换成列表对象。

        

 推导式式生成列表

        使用推导式可以非常方便的创建列表,在开发中经常使用,需要涉及到for和if语句。

 列表元素的增加和删除

        当列表增加和删除元素是,列表会自动进行内存管理,大大减少了程序员的负担,但这个特点设计列表元素的大量移动,效率较低。除非必要我们一般只在列表的尾部添加元素或删除元素,这样会大大提高变成效率。

append()方法

        原地修改列表对象,真正在列表尾部添加新的元素,速度最快,推荐使用。

        此方法不创建新的对象!

+运算符操作 

        并不是真正的尾部添加元素,而是创建新的列表对象;将原列表的元素的新列表的元素依次复制到新的列表中。这样,会涉及大量的复制操作,对于操作大量元素不建议使用。

         通过如上测试,我们发现变量a的地址发生了变化。也就是创建了新的列表对象。

extend()方法

        将目标列表的所有元素添加到原列表的尾部,属于原地操作,不创建新的列表对象。

 insert()方法

        使用insert()方法可以将指定位置元素插入到列表对象的任意指定位置。这样会让插入位置后面所有的元素进行移动,会影响处理速度。设计大量元素移动是,尽量表面使用。

        list.insert(index,x)

        在列表list的index位置处插入元素x

        注:指定位置index既可以正向搜索,也可以反向搜索。

                index >= len(list),此时是在队尾插入;

                index < -len(list),此时是在队头插入。

        类似发生这种移动的函数还有remove()、pop()、del()。它们在删除非尾部元素时也会发生操作位置后面元素的移动。

乘法扩展

        使用乘法扩展列表,生成一个新列表,新列表元素为原列表的多次重复,返回该新列表。

         适用于乘法扩展的,还有字符串、元组等。

 列表元素的删除

del删除

       del list[index]

        删除原列表中指定位置的元素。

        注:index可以是正向搜索,也可以是反向搜索,但要求index合法,否者抛出异常。

 pop()方法

        pop()删除院原列表指定位置元素,如果未指定则默认操作列表最后一个元素,返回被删除的元素。指定位置同样既可以正向搜索,也可以反向搜索,要求合法,否者抛出异常。

remove()方法 

        删除首次出现的指定元素,若该元素不存在则抛出异常。

        remove()方法没有返回值!!!即返回的是None

 

列表元素访问和计数

通过索引直接访问元素

        我们可以直接通过索引直接访问元素。索引的区间长度在[0,列表长度-1]或[-列表长度,-1]这个范围。超过这个范围则会抛出异常。

index()获得指定元素在列表中首次出现的索引

        index()可以获得指定元素在列表中首次出现的索引。若指定元素不出现则抛出异常。

        语法是:index(value,[start,[end]])

        其中start和end指定了搜索的范围,遵循着左闭右开的原则,[start,end)。

        注:搜索范围同样可以正向搜索,也可以反向搜索。

count()获得指定元素在列表中出现的次数

        count()可以返回指定元素在列表中出现的次数。

成员资格判定

        判断列表中是否存在指定的元素,我们可以使用count()方法,返回0则表示不存在,返回大于0则表示存在。但是,一般我们会使用更简洁的in关键字来判断,直接返回True或False。

切片操作

        列表的切片操作和字符串类似。

        切片slice操作可以让我们快速提取子列表或修改。标准格式为:

        [起始偏移量start:终止偏移量end[:步长]]

        注:当步长省略时数遍你可以省略第二个冒号。左闭右开,也可以说是包头不包尾。

        典型操作(三个数为正数):

操作和说明 示例 结果
[:]        提取整个列表
[10,20,30][:]
[10, 20, 30]
[start:]从start索引开始直到结尾 [10,20,30][1:] [20,30]
[:end]从头开始直到end-1 [10, 20, 30][:2] [10, 20]
[start:end]从start开始直到end-1 [10,20,30,40][1:3] [20,30]
[start:end:step]从start提取到end-1,步长是step [10,20,30,40,50,60][1:6:2]

[20, 40, 60]

        其它操作(三个量为负数)的情况:

示例 说明 结果
[10,20,30,40,50,60,70][-3:]
倒数第三个 [50, 60, 70]
[10,20,30,40,50,60,70][-5:-3]

倒数第五个到倒数第四个

(包头不包尾)

[30, 40]
[10,20,30,40,50,60,70][::-1]
步长为负,从右到左反向提取 [70, 60, 50, 40, 30, 20, 10]

        切片操作时,起始偏移量和终止偏移量不在[0:字符串长度]这个范围,也不会报错。起始偏移量小于0则会被当作0,终止偏移量大于“长度”会被当成“长度”。例如:

 列表的遍历

        for obj in listObj:
                print(obj)

复制列表所有元素到新列表对象

        如下代码是否实现列表元素复制?

list1=[30,40,50]
list2=list1

         只是将list2也指向了list1指向的对象,也就是说list1和list2持有地址值是相同的,列表元素本身并没有复制。

        可以通过如下简单方式,实现列表元素内容的复制:

list1=[30,40,50,60]
list2=[]+list1

        还可以使用copy模块,使用浅复制或深复制实现复制操作。

列表排序

原列表排序

        使用sort()方法,修改原列表,不新建列表的排序。sort()方法无返回值。

 排序后生成新的列表

        通过使用内置函数sorted()进行排序,这个方法返回新列表,不对原列表进行修改。

        通过上面操作,可以看出生成的列表对象b和c都是完全新的列表对象。

reversed()返回迭代器

         内置函数reversed()也支持逆序排序吗,与列表对象reverse()方法不同的是,内置函数reversed()不对原列表做任何修改,只是返回一个逆序列表的迭代器对象。

 列表相关的其他内置函数汇总

max和min

用于返回列表中的最大值和最小值

 sum

        对数值型列表的所有元素进行求和操作,对非数值列表则会报错。

多维列表

二维列表

        一维列表可以帮助我们存储一维、线性的数据。

        二维列表可以帮助我们存储而二维、表格的数据。

        例如下表的数据:

姓名 年龄 薪资 城市
高小一 18 30000 北京
高小二 19 20000 上海
高小三 20 10000 深圳

        源码:

a=[
    ["高小一",18,30000,"北京"],
    ["高小二",19,20000,"上海"],
    ["高小一",20,10000,"深圳"]
  ]

        内存结构图:

元组tuple

        列表属于可变序列,可以任意修改列表中的元素。元组属于不可变序列,不能修改元组中的元素。因此,元组没有增加元素、修改元素、删除元素相关的方法。

        在元组中重点掌握元组的创建和删除,元组中元素的访问和计数即可。

        元组支持以下操作:

                1.索引访问

                2.切片操作

                3.连接操作

                4.成员关系操作

                5.比较运算操作

                6.计数:元组长度len()、最大值max()、最小值min()、求和sum()等。

元组的创建

        1.通过()创建元组。小括号可以省去。

                a=(10,20,30)  或者  a= 10,20,30

        如果元组只有一个元素,则必须后面加逗号。这时因为解释器会把(1)解释我整数1,(1,)解释为元组。

        2.通过tuple()创建元组

        tuple(可迭代的对象)

        例如:

  

         总结:

        tuple()可以接受列表、字符串、其他序列类型、迭代器等生成组。

        list()可以接受元组、字符串、其他序列类型、迭代器生成列表。

元组的元组访问和计数

        1.元组的元素不能修改

         2.元组的元素访问和列表一样,只不过返回的依然是元组对象。

         3.列表关于排序的方法list.sort()是修改原列表对象,元组没有该方法。如果要对元组排序,只能使用内置函数sorted(tupleObj),并生成新的列表对象

zip

        zip(列表1,列表2,……)将多个列表对应位置的元素组合成为元组,并返回这个zip对象。

 生成器推导式创建元组

        从形式上看,生成器推导和列表推导类似,只是生成器推导式使用小括号。列表推导式直接生成列表对象,生成器推导式生成的不是列表也不是元组,而是一个生成器对象

        我们可以通过生成器对象,转化成列表或者元组。也可以使用生成器对象_next_()方法进行遍历,或者直接作为迭代器对象来使用。不管什么方式使用,元素访问结束后,如果需要重新访问其中元素,必须重新创建生成器对象。

        生成器使用测试:

元组总结

        1.元组的核心是不可变序列。

        2.元组的访问和处理速度比列表快。

        3.与整数和字符串一样,元组可以作为字典的键,列表则永远不能作为字典的键使用。

字典dict

        字典是“键值对”的无序可变序列,字典中的每一元素都是一个“键值对”,包含:“键对象”和“值对象”。我们可以通过“键对象”实现快速获取、删除、更新对应的“值对象”。

        列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。“键”是任意不可变数据类型,比如:整数、浮点数、字符串、元组。但是:列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。

        一个典型的字典的定义方式:

                a={'name':'phh','age':18,'job':'programmer'}

字典的创建

        1.我们可以通过{}、dict()来创建字典对象。

        2.通过zip()创建字典对象

         3.通过fromkeys创建值为空的字典

字典元素的访问

        为了测试各种访问方法,我们这里设定一个字典对象:

                a={'name':'phh','age':18,'job':'programmer'}

        1.通过 [键] 获得 “值”。若键不存在,则抛出异常。

        2.通过get()方法获得“值”。推荐使用。优点是:指定键不存在,返回None;也可以设定指定键不存在是默认返回的对象。推荐使用get()获取“值对象”。

         3.列出所有的键值对

        4.列出所有的键,列出所有的值。

         5.len() 键值的数目

 

         6.检测一个“键”是否在字典中。

字典元素添加、修改、删除

        1.给字典新增“键值对”。

        如果“键”已经存在,则覆盖旧的键值对;如果“键”不存在,则新增“键值对”。

 

         2.如果使用update()将字典中所有键值对全图添加到旧字典上。如果key值有重复,则直接覆盖。

        3.字典中元素的删除,可以使用del()方法;或者使用clear()删除所有键值对;pop()删除指定键值对,并返回对应的“值对象”。

         4.popitem()随机删除和返回该键值对。字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念;popitem弹出随机的项,因为字典并没有“最后的元素”或则其它有关顺序的概念。若想一个接一个地移除处理项,这个方法就非常有效(因为不用获取键的列表)。

序列解包

        序列解包可以用于元组、列表、字典。序列解可以让我们方便对多个变量赋值。

        序列解包用于字典时,默认是对'“键”进行操作;如果需要对键值进行操作,则需要使用items();如果需要对“值”进行操作,则需要使用values()。

 

 表格数据使用字典和列表存储,并实现访问

 

 

源代码:

r1 = {"name":"高小一","age":18,"salary":30000,"city":"北京"} 
r2 = {"name":"高小二","age":19,"salary":20000,"city":"上海"} 
r3 = {"name":"高小五","age":20,"salary":10000,"city":"深圳"} 

tb = [r1,r2,r3]     

#获得第二行的人的薪资 
print(tb[1].get("salary"))   
  
#打印表中所有的的薪资 
for i in range(len(tb)): # i -->0,1,2 
    print(tb[i].get("salary")) 

#打印表的所有数据 
for i in range(len(tb)):                             
    print(tb[i].get("name"),tb[i].get("age"),tb[i].get("salary"),tb[i].get("city"))

字典核心底层原理

        字典的核心是散列表。散列表是一个稀疏数组(总是有空白的数组),数组的每个单元叫做bucket有两部分:一个是键对象的引用,一个是值对象的引用。

        由于,所有bucket结构和大小一致,我们可以通过偏移量来读取指定

根据键查找“键值对”的底层过程

         明白一个键值对是如何存储到数组中,根据键对象取到值对象,理解起来就简单了。

 

         当我们a.get('name'),就是根据键‘name'查找到“键值对”,从而找到值对象'phh'。

        第一步,计算‘name’对象的散列值:

        和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。 假设数组长度为 8,我们可以拿计算出的散列值的最右边 3 位数字作为偏移量,即“101”,十进制是数字 5。我们查看偏移量 5,对应的 bucket 是否为空。如果为空,则返回 None。如果不为空, 则将这个 bucket 的键对象计算对应散列值,和我们的散列值进行比较,如果相等。则将对 应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完后, 仍然没有找到。则返回None。
        

        用法总结:

        1.键必须可散列

                (1) 数字、字符串、元组,都是可散列的。

                (2) 自定义对象需要支持下面三点:

                        支持hash()函数

                        支持通过__eq__()方法检测相等性。

                        若a==b为真,则hash(a)==hash(b)为真。

        2.字典在内存中开销巨大,典型的空间换时间。

        3.键查询速度很快。

        4.往字典添加新键可能导致扩容,导致散列中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。

集合set

        集合是无序可变,元素不能重复。实际上,集合底层是字典实现,集合所有元素都是字典中的“键对象”,因此是不能重复且唯一的。

集合的创建和删除

        1.使用{}创建对象,并使用add()方法添加元素。

        在使用add()方法时,添加已经存在集合中元素不会抛出异常。

        2.使用set(),将列表、元组等可迭代对象转为集合。如果原数据存在重复数据,则值保留一个。

        3.remove()删除指定元素;clear()清空整个集合。

 

 集合相关操作

        像数学中概念一样,Python对集合也提供了并集、交集、差集等运算。

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python之序列 的相关文章

随机推荐

  • 在 Windows 下搭建 Appium + Android 自动化测试环境

    前言 本来并不打算写这么一篇文章 但是实践下来发现网上的各种教程里大致有两个问题 一是文章有些跟不上时代 目前android开发和测试的技术更新都比较快 内容有些过期 二是细节部分不是太完整 拼拼凑凑也能完成 但对新手来说就比较痛苦 那么
  • 【带限制的完全背包】Educational Codeforces Round 133 (Rated for Div. 2) D. Chip Move

    题意 给定 n n n 和 k k k 初始步长为 k k k 每次可以走
  • 逆向python生成的可执行文件

    先安装pyinstaller pip install pyinstaller i https pypi douban com simpl 写一个简单的脚本 print hello world pyinstaller基本用法 常用的可选参数如
  • (纯干货,看完不懂你找我)Python+Pytest+Allure+Git+Jenkins接口自动化框架

    Python Pytest Allure Git Jenkins接口自动化框架 一 接口基础 二 项目说明 四 项目功能 五 代码设计与功能说明 六 后期优化 七 感想 一 接口基础 接口测试是对系统和组件之间的接口进行测试 主要是效验数据
  • 【图像去模糊】Deep Multi-scale Convolutional Neural Network for Dynamic Scene Deblurring论文笔记

    一 论文概述 一般因动态场景造成的非均匀模糊是图像去模糊中一个具有挑战性的问题 这类模糊由相机抖动 场景深度以及多个对象运动造成 消除这类复杂运动模糊 传统的基于简单假设的方法不在适用 在本文中 作者提出了一种多尺度卷积神经网络 以端到端的
  • 感知机模型

    目录 一 感知机模型 1 1定义 感知机 1 2几何解释 二 损失函数 三 学习算法 3 1感知机学习算法的原始形式 3 2感知机学习算法的对偶形式 一 感知机模型 1 1定义 感知机 假设输入空间 特征空间 是 输出空间是 输入表示实例的
  • 【前端性能】常见前端性能优化

    常见性能优化 前言 一 图片优化 1 雪碧图 图片精灵 2 图片压缩 3 字体图标代替图片 4 webp图片 二 DOM优化 1 缓存DOM节点查找的结果 2 防抖和节流 3 事件代理 4 减少合并DOM操作 5 DOM读写分离 6 DOM
  • VMware虚拟机扩容——Ubuntu的/dev/sda1分区挂在根目录(“/“)下用LVM(逻辑卷管理)模式扩容无效

    一 问题描述 在VMware虚拟机装了Ubuntu18 04 一开始分配的内存是20多个G 如下图 用了一段时间后发现不够用了 需要扩容 然后上网查了一下虚拟机扩容的方法 但是大多数教程的情况是 根目录 挂在类似 dev xxx xxxro
  • ThinkpadE480 win10改win7

    Thinkpad E480win10改win7 电脑配置信息 i7 8550u 直接进PE 一键装机 选择win7镜像安装到系统盘 安装后进系统失败 没有修改bios信息 win10系统改win7设置bios方法图文教程 一起来围观吧 ht
  • Vue3导出excel,使用js-table2excel

    装依赖 npm install js table2excel vue中引入 import table2excel from js table2excel 使用 const column title sn key sn type text t
  • Mysql命令及增删改查操作

    测试工程师的目的是找出软件的不足 并告诉开发工程师 出现问题的环境 操作步骤和输入输出数据 优秀的测试工程师 需要告诉开发团队 软件的不足 这类不足会导致什么情况 如何避免 以及如何去修改 这是为什么高级软件测试工程师比开发工程师工资高的原
  • Qt应用开发(基础篇)——组合框容器 QGroupBox

    一 前言 QGroupBox继承于QWidget 是一个带有标题的组合框架容器控件 QGroupBox组合框容器自带一个顶部标题 一个面板 面板内部展示各种各样的部件 标题用来解释这些部件为什么集合在一起 并且支持键盘快捷方式切换部件焦点
  • c++读文件(一次全读/每行读/多次读)

    我以为这些都很容易在网上找到 谁知网上乱七八糟的东西太多 让我找了很久 开发环境为Windows VS2013 一次全读 std ifstream t path 读文件ifstream 写文件ofstream 可读可写fstream std
  • 开源IOT——一个最小的物联网系统设计方案及源码

    或许这个可以当成是你的毕业设计又或者你可以用它来控制你想控制的东西 总之你可以用它来做一个最小的物联网系统 不过 在这里可能没有那么复杂的功能 因为强调的是最小 BareMinimum 这也是为什么我没有改Arduino上面的工程名的原因
  • [附源码]计算机毕业设计校园疫情管理系统Springboot程序

    项目运行 环境配置 Jdk1 8 Tomcat7 0 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 SSM mybatis Ma
  • SpringMVC SpringBoot Get请求接收复杂参数

    前沿 对于复杂的接口请求 一般都用POST JSON数据的方式 后端用 RequestBody接收 但是对于某些有洁癖的人或者想严格遵循类Restful风格的人来讲 查询数据就是想用GET 怎么实现呢 Request Data public
  • can总线的示波器检测方法

    整理自网络 stm32的can总线是在APB1上的 stm32f10x的主频是72Mhz can外设时钟是36Mhz stm32f2xx的主频是120Mhz can外设时钟是30Mhz STM32 APB1和APB2区别 APB2负责AD
  • Linux统计某文件夹下文件、文件夹的个数

    http blog sina com cn s blog 464f6dba01012vwv html 统计某文件夹下文件的个数 ls l grep wc l 统计某文件夹下目录的个数 ls l grep wc l 统计文件夹下文件的个数 包
  • 瞧瞧,这样的「函数」才叫 Pythonic

    在机器学习中 我们经常需要使用类和函数定义模型的各个部分 例如定义读取数据的函数 预处理数据的函数 模型架构和训练过程的函数等等 那么什么样的函数才是漂亮的 赏心悦目的代码呢 本期教程 会从命名到代码量等六方面探讨如何养成美妙的函数 文末有
  • Python之序列

    序列是一种数据存储方式 用来存储一系列的数据 在内存中 序列就是一块用来存放多个值的连续空间 比如一个整数序列 10 20 30 40 可以这样表示 由于Python3中一切皆对象 在内存中实际是按照如下方式储存的 a 10 20 30 4