【python基础】python可变序列与不可变序列

文章目录

  • 前言
  • 一、序列类型定义
  • 二、对序列类型的切片操作
  • 三、使用 + 与 * 对序进行操作
  • 四、增量赋值 += 和 *=


前言

本文主要讲可变序列与不可变序列一些简单的应用。

一、序列类型定义

按序列能否被修改分为:可变序列与不可变序列。
可变序列:可以进行增、删、改等操作序列。比如:比如列表、集合等。
不可变序列:不可以进行增、删、改等操作序列。比如:元组、字符串等。

  • 可变序列

举例一:列表

list1=[x for x in range(8)]
print('原列表:',id(list1))

list1.append('hello')
print('增加变量后的列表:',id(list1))

输出:

原列表: 1554734032320
增加变量后的列表: 1554734032320

举例二:集合

set1={1,2,3,4,5}
print("原集合:",id(set1))

set1.add('a')
print("增加元素后的集合:",id(set1))

输出:

原集合: 1554733828128
增加元素后的集合: 1554733828128
  • 不可变序列

举例三:元组

tuple1=(1,2,3,4)
print("原元组:",id(tuple1))

tuple1*=3
print("复制后的元组:",id(tuple1))

输出:

原元组: 1554733957184
复制后的元组: 1554723851136

举例四:字符串

str1='hello'
print("原字符串:",id(str1))

str1*=3
print("替换修改后的字符串:",id(str1))

输出:

原字符串: 1554730216624
替换修改后的字符串: 1554733243696

结论:不可变序列在内存中是不会改变的,如果对不可变序列做出改变,会将该序列存储在新的地址空间中,而原来的序列因为垃圾回收机制,会被回收;可变序列发生改变时,是不会改变地址的,而是改变内存中的值,或者扩展内存空间。


二、对序列类型的切片操作

举例:a[i:j:k]取值

s="hello world"

s[::3] #间隔三个字符取值
#输出:
#'hlwl'

s[::-1] #倒序
#输出:
#'dlrow olleh'

s[:5:2]
#输出:
#'hlo'

切片基础理解可以参考:https://blog.csdn.net/sodaloveer/article/details/134197327

举例二:切片对象slice(a,b,c)

seq(start:stop:step)求解时,解释器用seq.getitem(slice(start,end,step))。

s="hello world"

first=slice(0,9) #先创建一个slice对象
last=slice(9,None)

s[first]
#输出:
#'hello wor'

s[last]
#输出:
#'ld'

举例三:多维切片

[ ] 内逗号隔开传入多个切片对象,从而实现多维切片,广泛用于numpy中,list不支持这种操作。

import numpy as np 
a=np.array(range(24))
a=a.reshape((2,3,4))
a

#输出:
#array([[[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]],
#
#       [[12, 13, 14, 15],
#        [16, 17, 18, 19],
#        [20, 21, 22, 23]]])

a[1,2,3] #第2个数组的第三行第四列。
#输出:
#23

a[1,2,1:3]  #第2个数组的第3行第二、四列。
#输出:
#array([21, 22])

a[1,...] #第2个数组
#输出:
#array([[12, 13, 14, 15],
#       [16, 17, 18, 19],
#       [20, 21, 22, 23]])

举例四:切片赋值

  • 切片长度和赋值的数组长度可以不相等
list1=[x for x in range(10)]
list1
#输出:
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list1[2:5]=[20,30]
list1
#输出:
#[0, 1, 20, 30, 5, 6, 7, 8, 9]

list1[2:4]=[1,1,1,1,1,1,1,1]
list1
#输出:
#[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 9]
  • 间隔切片时必须要相等
list1[::2]=[666,777]
list1

在这里插入图片描述

list1[::2]=[111,222,333,444,666,777,888,999]
list1
#输出:
#[111, 1, 222, 1, 333, 1, 444, 1, 666, 1, 777, 6, 888, 8, 999]

注意: 传入值的形式一定要用[]。

三、使用 + 与 * 对序进行操作

使用 + 与 * 对序进行操作时,python并不修改原有的操作对象,而是构建一个全新序列。

list1=[x for x in range(5)]
list2=[x for x in range(5,10)]

list1+list2
#输出:
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

list1*2
#输出:
#[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]

print('原有的列表并不改变:',list1)
#输出:
#[0, 1, 2, 3, 4]

注意: 对于列表中的元素为引用时,慎用+和*。

list1=[[1,2,3]]

list2=list1*3
list2
#输出:
#[[1, 2, 3], [1, 2, 3], [1, 2, 3]]

list2[0][0]='hello'
#输出:
#[['hello', 2, 3], ['hello', 2, 3], ['hello', 2, 3]]

结论:由上可见,list1是一个只有一个元素的列表,这个元素是一个指向列表[1,2,3]的引用。list2=list1*3操作,则建立三个这样的引用,但作为list2的元素,三个元素都是指向同一个列表对象,所以我们使用第一个元素(list2[0][0]=‘hello’)去修改指向的列表的值时,list2列表中每一个引用的第一个元素都被改变了。
如果只修改引用是没有问题的,如下例所示:

list2[0]="world"
#输出:
#['world', ['hello', 2, 3], ['hello', 2, 3]]

结论:由上可见,此时我们修改了list2的第一个元素,把其重新指向了一个新建的字符串对象。而原来指向的列表没有发生改动,所以后两个元素此时不会发生变化。


四、增量赋值 += 和 *=

就地乘法: *= ,背后是__imul__特殊方法。
就地加法: += ,背后是__iadd__特殊方法,和a.extend(b)一样的效果。若a未实现该特殊方法,Python将退一步调用__add__方法,得到一个求和对象,然后赋值给a。

  • 对于支持就地加法或乘法的序列类型(可变类型),使用+=或*=时,Python不会新建一个对象。如下例所示,a的地址并未发生变化。
a=[x for x in range(5)]
b=[y for y in range(5,10)]

print('原序列:',a,'\n','原序列地址:',id(a))
#输出:
#原序列: [0, 1, 2, 3, 4] 
#原序列地址: 1554755401920

a+=b
print('就地加法后的序列:',a,'\n','就地加法后的序列地址:',id(a))
#输出:
#就地加法后的序列: [0, 1, 2, 3, 4] 
#就地加法后的序列地址: 1554755401920
  • 对于不支持就地加法或乘法的序列类型(不可变类型),使用+=或*=时,Python会新建一个对象。如下例所示,tuple1的地址发生变化。
tuple1=(1,2,3)
print('原序列:',tuple1,'\n','原序列地址:',id(tuple1))
#输出:
#原序列: (1, 2, 3) 
#原序列地址: 1554755553856
 
tuple1*=2
print('就地乘法后的序列:',tuple1,'\n','就地乘法后的序列地址:',id(tuple1))
#输出:
#就地乘法后的序列: (1, 2, 3, 1, 2, 3) 
#就地乘法后的序列地址: 1554728975712

参考文章:
https://zhuanlan.zhihu.com/p/33488349

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

短期风速预测|LSTM|ELM|批处理(matlab代码)

1主要内容 该程序是预测类的基础性代码,程序对河北某地区的气象数据进行详细统计,程序最终得到pm2.5的预测结果,通过更改数据很容易得到风速预测结果。程序主要分为三部分,分别是基于LSTM算法、基于ELM算法和基于LSTM和批处理组合…

vivado产生报告阅读分析15-时序报告11

Report Clock Domain Crossings “ Clock Domain Crossings (CDC) ” ( 时钟域交汇 ) 报告可对设计中的时钟域交汇执行结构分析。此信息可用于识别潜在不安全的 CDC , 此类 CDC 可能导致亚稳态或数据一致性问题。虽然 CDC 报告与“ Clock …

2023年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2023年危险化学品经营单位主要负责人证模拟考试题库及危险化学品经营单位主要负责人理论考试试题是由安全生产模拟考试一点通提供,危险化学品经营单位主要负责人证模拟考试题库是根据危险化学品经营单位主…

LongAccumulator

原子操作之LongAccumulator 和LongAdder的区别在于,LongAdder是在Cell里面只能做加减操作,不能乘除,而LongAccumulator就可以定义乘除操作。原理和LongAdder都是一样的,一个Base和一个Cells数组。 原文跳转地址

基于docker实现JMeter分布式压测

为什么需要分布式? 在工作中经常需要对一些关键接口做高QPS的压测,JMeter是由Java 语言开发,没创建一个线程(虚拟用户),JVM默认会为每个线程分配1M的堆栈内存空间。受限于单台试压机的配置很难实现太高的并…

prometheus热更新失败failed to reload config

一、问题描述 k8s部署的prometheus服务在请求热更新时报错: failed to reload config: one or more errors occurred while applying the new configuration (--config.file"/etc/prom/config/file/prometheus.yml")请求命令:curl -X POST http://monitor-cp-prom:…

【Delphi】开发IOS 程序,TLabel 中英文字对齐(水平),一行代码解决显示对齐问题!

目录 一、问题现象: 二、解决方案(一行代码解决ios对齐问题): 三、解决后效果: 四、后记: 一、问题现象: 在用 Delphi 开发ios程序时,使用TLabel控件显示,会出现中英…

Epub书籍阅读工具

Epub书籍阅读工具 前言WIndows总结Neat ReaderAquile ReaderWPS Android总结Neat Reader掌阅 前言 Epub文件为电子书文件格式,此格式的电子书相比txt书籍,增加了目录跳转功能,并可以显示图片。本文介绍WIndows和Android端的epub书籍阅读工具…

如何做好项目管理?年薪百万项目大佬一直在用这11张图

大家好,我是老原。 日常工作中,我们会遇到各种大大小小的工作项目,如何能让项目保质保量的完成,是我们项目经理的目标。 项目管理的流程可以说是由一系列的子过程组成的,它是一个循序渐进的过程,所以不能…

ros2不同机器通讯时IP设置

看到这就是不同机器的IP地址,为了避免在路由器为不同的机器使用DHCP分配到上面的地址,可以设置DHCP分配的范围:(我的路由器是如下设置的,一般路由器型号都不一样,自己找一下) 防火墙设置-----&…

langchain 部署组件-LangServe

原文:🦜️🏓 LangServe | 🦜️🔗 Langchain LangServe 🚩 We will be releasing a hosted version of LangServe for one-click deployments of LangChain applications. Sign up here to get on the wa…

Bracket Sequence ——卡特兰数

平衡括号序列是一个仅由括号"("和")"组成的字符串。 一天,卡罗尔问贝拉长度为2N(N对括号)的平衡括号序列的数量。作为心算大师,她立刻算出了答案。所以Carol问了一个更难的问题:长度为2N&#xff…

易货:一种新型的商业模式

随着经济的发展和社会的进步,人们对于交易的需求和方式也在不断变化。传统的商业模式已经无法满足人们对于多元化、个性化、高效的需求。在这样的背景下,易货模式逐渐走进人们的视野,成为一种新型的商业模式。 易货模式是一种以物换物的交易方…

Linux超简单部署个人博客

1 安装halo 1.1 切换到超级用户 sudo -i 1.2 新建halo文件夹 mkdir ~/halo && cd ~/halo 1.3 编辑docker-compose.yml文件 vim ~/halo/docker-compose.yml 英文输入法下,按 i version: "3"services:halo:image: halohub/halo:2.10container_…

xss-labs靶场6-10关

文章目录 前言一、靶场6-10关1、关卡62、关卡73、关卡84、关卡95、关卡10 总结 前言 此文章只用于学习和反思巩固xss攻击知识,禁止用于做非法攻击。注意靶场是可以练习的平台,不能随意去尚未授权的网站做渗透测试!!! …

新手必看!!附源码!!STM32通用定时器输出PWM

一、什么是PWM? PWM(脉冲宽度调制)是一种用于控制电子设备的技术。它通过调整信号的脉冲宽度来控制电压的平均值。PWM常用于调节电机速度、控制LED亮度、产生模拟信号等应用。 二、PWM的原理 PWM的基本原理是通过以一定频率产生的脉冲信号&#xff0…

Godot

前言 为什么要研究开源引擎 主要原因有: 可以享受“信创”政策的红利,非常有利于承接政府项目。中美脱钩背景下,国家提出了“信创”政策。这个政策的核心就是,核心技术上自主可控。涉及的产业包括:芯片、操作系统、数据…

LeetCode59.螺旋矩阵

LeetCode59.螺旋矩阵 1.问题描述2.解题思路3.代码 1.问题描述 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 输入:n 3 输出:[[1,2,3],[8,9,…