Python(六十九)为什么要将元组设计成不可变序列

news2024/9/22 15:49:58

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。
☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无论你是学生、职场人士还是对编程感兴趣的爱好者,都能从中受益。跟着我的学习笔记一起学习python吧。
🌙专栏目标:本专栏的目标是帮助我自己记忆、方便回顾所学知识以及帮助其他想学习python的小伙伴掌握Python编程语言的基本概念和技巧,并逐步提高我们的编程能力。通过这个专栏,我们将学会如何编写Python代码,理解各种数据类型、控制结构和函数,掌握常用的Python模块和库,以及应用Python解决实际问题。

⭐️ 专栏主要内容: 主要学习python的开发环境搭建;Python的基础知识,包括变量、数据类型、条件语句和循环等;python的数据结构和算法;python的函数和模块;python的文件处理等。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:从零开始的Python入门之路

在这里插入图片描述

Python提供了多种数据类型来满足不同的需求,其中之一就是元组(Tuple)。元组是一种不可变的有序序列,它在Python中具有重要的作用。

文章目录

    • 为什么要将元组设计成不可变序列
      • 1. 在多任务环境下,同时操作对象时不需要加锁
      • 2. 在程序中尽量使用不可变序列
    • 注意事项:元组中存储的是对象的引用
      • a. 如果元组中对象本身是不可变对象,则不能再引用其他对象
      • b. 如果元组中对象是可变对象,则可变对象的引用不允许改变,但数据可以改变

为什么要将元组设计成不可变序列

1. 在多任务环境下,同时操作对象时不需要加锁

在多任务环境中,多个任务可能同时访问和修改同一个数据。如果数据是可变的,那么在多任务同时修改数据时,就需要使用锁(Lock)来保证数据的一致性。而元组作为不可变序列,不会被修改,因此在多任务环境下,我们可以放心地同时访问元组对象,无需加锁。

示例代码:

import threading

# 定义一个可变列表
my_list = [1, 2, 3]

# 定义一个不可变元组
my_tuple = (1, 2, 3)

# 定义一个函数,用于修改列表和元组
def modify_data():
    global my_list, my_tuple
    for _ in range(1000000):
        my_list.append(4)
        # 元组不支持修改,下面的代码会抛出异常
        my_tuple += (4,)

# 创建两个线程,同时修改数据
thread1 = threading.Thread(target=modify_data)
thread2 = threading.Thread(target=modify_data)

# 启动线程
thread1.start()
thread2.start()

# 等待线程执行完毕
thread1.join()
thread2.join()

print("列表长度:", len(my_list))
print("元组长度:", len(my_tuple))

运行结果:

列表长度: 4000004
Traceback (most recent call last):
  File "example.py", line 18, in modify_data
    my_tuple += (4,)
TypeError: 'tuple' object does not support item assignment

从运行结果可以看出,多个线程同时修改列表时,列表的长度会变得非常大,而多个线程同时修改元组时,会抛出异常。这说明元组的不可变性在多任务环境下起到了重要的作用。

2. 在程序中尽量使用不可变序列

在编写程序时,我们通常希望数据是安全的、不可变的。不可变序列具有以下优点:

  • 安全性:不可变序列可以保护数据的完整性,防止意外修改数据。
  • 可散列性:不可变序列可以作为字典(Dictionary)的键值,因为字典要求键值必须是可散列的(Hashable)。
  • 性能优化:不可变序列在创建后不可修改,因此可以进行一些优化,例如缓存计算结果,提高程序的执行效率。

示例代码:

# 使用可变列表
my_list = [1, 2, 3]
my_list.append(4)
print(my_list)  # 输出:[1, 2, 3, 4]

# 使用不可变元组
my_tuple = (1, 2, 3)
# 元组不支持修改,下面的代码会抛出异常
my_tuple.append(4)
print(my_tuple)

运行结果:

[1, 2, 3, 4]
AttributeError: 'tuple' object has no attribute 'append'

从运行结果可以看出,使用列表可以方便地修改数据,而使用元组则无法修改数据。因此,在程序中,如果我们希望数据是不可变的,就应该使用元组。

注意事项:元组中存储的是对象的引用

在使用元组时,需要注意元组中存储的是对象的引用,而不是对象本身。这意味着元组中的元素可以是任何对象,无论是不可变对象还是可变对象。

a. 如果元组中对象本身是不可变对象,则不能再引用其他对象

示例代码:

# 定义一个元组,包含一个整数和一个字符串
my_tuple = (1, "hello")

# 尝试修改元组中的整数
my_tuple[0] = 2  # 抛出异常:TypeError: 'tuple' object does not support item assignment

# 尝试修改元组中的字符串
my_tuple[1] += " world"  # 抛出异常:TypeError: 'tuple' object does not support item assignment

print(my_tuple)

运行结果:

Traceback (most recent call last):
  File "example.py", line 5, in <module>
    my_tuple[0] = 2
TypeError: 'tuple' object does not support item assignment

从运行结果可以看出,尝试修改元组中的整数和字符串都会抛出异常。这是因为整数和字符串都是不可变对象,它们的值无法修改。

b. 如果元组中对象是可变对象,则可变对象的引用不允许改变,但数据可以改变

示例代码:

# 定义一个元组,包含一个列表
my_tuple = ([1, 2, 3],)

# 尝试修改元组中的列表
my_tuple[0].append(4)

print(my_tuple)  # 输出:([1, 2, 3, 4],)

运行结果:

([1, 2, 3, 4],)

从运行结果可以看出,尽管元组中的列表是可变对象,我们可以修改列表中的数据,但是不能修改列表的引用。这就意味着我们可以向列表中添加、删除元素,但不能将列表替换为另一个列表。

参考链接:

  • Python官方文档 - 元组 (tuple)
  • Python官方文档 - 锁 (Lock)
  • Python官方文档 - 可散列类型 (Hashable)

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

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

相关文章

git bash 安装sdkadmin

1.下载相关安装包,复制到git 安装目录 D:\software\Git\mingw64\bin 2. 运行 curl -s "https://get.sdkman.io" | bash

心跳跟随的心形灯(STM32(HAL)+WS2812+MAX30102)

文章目录 前言介绍系统框架原项目地址本项目开发开源地址硬件PCB软件功能 详细内容硬件外壳制作WS2812级联及控制MAX30102血氧传感器0.96OLEDFreeRTOS 效果视频总结 前言 在好几年前&#xff0c;我好像就看到了焊武帝 jiripraus在纪念结婚五周年时&#xff0c;制作的一个心跳跟…

10 日志系统(下)

10 日志系统&#xff08;下&#xff09; 本文内容 日志系统分为两部分&#xff0c;其一是单例模式与阻塞队列的定义&#xff0c;其二是日志类的定义与使用。 本篇将介绍日志类的定义与使用&#xff0c;具体的涉及到基础API&#xff0c;流程图与日志类定义&#xff0c;功能实现…

Android 刷新与显示

目录 屏幕显示原理&#xff1a; 显示刷新的过程 VSYNC机制具体实现 小结&#xff1a; 屏幕显示原理&#xff1a; 过程描述&#xff1a; 应用向系统服务申请buffer 系统服务返回一个buffer给应用 应用开始绘制&#xff0c;绘制完成就提交buffer&#xff0c;系统服务把buffer数据…

第三章 CUDA编译器环境配置篇

cuda教程目录 第一章 指针篇 第二章 CUDA原理篇 第三章 CUDA编译器环境配置篇 第四章 kernel函数基础篇 第五章 kernel索引(index)篇 第六章 kenel矩阵计算实战篇 第七章 kenel实战强化篇 第八章 CUDA内存应用与性能优化篇 第九章 CUDA原子(atomic)实战篇 第十章 CUDA流(strea…

Fatal error, can‘t open config file ‘/myredis/redis.conf‘: No such file or directory

在学习Redis到主从复制部分&#xff0c;进行相关练习&#xff0c;基本过程如下 1.首先将redis.conf文件cp到自建myredis文件夹中&#xff0c;并配置不同端口号的redis.conf redisXXXX.confd的配置内容如下 &#xff1a; include /myredis/redis.conf pidfile /var/run/redis_…

压力测试与测试工具jmeter的介绍

目录 一、性能指标 二、jmeter &#xff08;一&#xff09;JMeter 安装 &#xff08;二&#xff09;JMeter 压测示例 1、添加线程组 2、添加 HTTP 请求 3、添加监听器 4、启动压测&查看分析结果 &#xff08;三&#xff09;JMeter Address Already in use 错误解决 压力测…

Flutter运行app时向logcat输出当前打开的界面路径且点击可跳转

当一个项目大了目录文件多了&#xff0c;我们往往会为了找到一个文件花费大量的时间和精力&#xff0c;为了快捷方便的调试我们的项目&#xff0c;我们往往需要在打开app运行的时候需要知道当前打开的界面的文件在哪儿&#xff0c;我们这个代码就能快捷的知道我们app正在打开的…

《HeadFirst设计模式(第二版)》第五章代码——单例模式

代码文件目录&#xff1a; 初始版本&#xff1a; package Chapter5_SingletonPattern.origin;/*** Author 竹心* Date 2023/8/5**/public class Singleton {private static Singleton uniqueInstance;private Singleton(){}public static Singleton getInstance(){if(uniqueIn…

2023牛客暑期多校训练营6-A Tree

2023牛客暑期多校训练营6-A Tree https://ac.nowcoder.com/acm/contest/57360/A 文章目录 2023牛客暑期多校训练营6-A Tree题意解题思路代码 题意 解题思路 最大价值和这个数据范围&#xff0c;一眼 d p dp dp。 直接在树上并不好处理&#xff0c;问题是如何有效转化、处理…

黑马程序员SpringMVC练手项目

目录 1、需求 2、项目准备 pom.xml SQL jdbc.properties log4j.properties applicationContext.xml spring-mvc.xml web.xml 3、工作流程 4、难点 项目已经上传到gitee&#xff1a;https://gitee.com/xzl-it/my-projects 1、需求 SpringMVC项目练习&#xff1a;数…

每日一题——反转单链表

反转单链表 题目链接 下面主要介绍两种方法&#xff1a; 方法一&#xff1a; 利用三个指针变量进行反转 具体过程如图所示&#xff1a; 注意&#xff1a;循环的结束的条件为cur NULL而不是next NULL 实现代码&#xff1a; struct ListNode* reverseList(struct ListNode* …

STL容器适配器 -- stack和queue(使用+实现)(C++)

stack和queue stackstack的介绍stack的使用stack的实现 queuequeue的介绍queue的使用queue的实现 deque简单介绍deque&#xff08;双端队列&#xff09;双开口连续打引号的原因 deque底层结构deque的迭代器封装结构&#xff08;复杂&#xff09;deque的优缺点 栈和队列数据结构…

LLM reasoners 入门实验 24点游戏

LLM reasoners Ber666/llm-reasoners 实验过程 实验样例24games&#xff0c;examples/tot_game24&#xff0c;在inference.py中配置使用代理和open ai的api key。 首先安装依赖 git clone https://github.com/Ber666/llm-reasoners cd llm-reasoners pip install -e .然后…

JVM入门到精通

一、JVM概念 1.1、什么是JVM Java Virtual Machine&#xff1a;Java虚拟机&#xff0c;用来保证Java语言跨平台 Java虚拟机可以看做是一台抽象的计算机&#xff0c;如同真实的计算机那样&#xff0c;它有自己的指令集以及各种运行时内存区域 Java虚拟机与Java语言并没有必然…

Maven-搭建私有仓库

使用NEXUS REPOSITORY MANAGER 3在Windows上搭建私有仓库。 NEXUS REPOSITORY MANAGER 3 是一个仓库管理系统。 下载NEXUS3 官网上是无法下载的,所以网上搜nexus-3.18.1-01-win64就能搜到,下载即可。 安装NEXUS3 下载nexus-3.18.0-01-win64.zip至相应目录下(路径不要有中文)。 …

[Realtek sdk-3.4.14b]RTL8197FH-VG+RTL8812F WiFi开启访客网络之后无法扫描到SSID问题分析及解决方案

问题描述 realtek sdk-3.4.14b 开启访客网络之后,发现无法扫描到SSID,可以看到接口已经up,但是设备无法搜到WiFi热点 问题分析 查看网口状态 ifconfig查看wlan0-va0接口TX/RX的数据包都是0,表示没有发送或者接收到数据包,正常wifi启动之后,都会有Beacon包发出,也会接…

【Redis】——RDB快照

Redis 是内存数据库&#xff0c;但是它为数据的持久化提供了两个技术&#xff0c;一个是AOF日志&#xff0c;另一个是RDB快照&#xff1a; AOF 文件的内容是操作命令&#xff1b;RDB 文件的内容是二进制数据。 RDB 快照就是记录某一个瞬间的内存数据&#xff0c;记录的是实际…

Vue中,$forceUpdate()的使用

在Vue官方文档中指出&#xff0c;$forceUpdate具有强制刷新的作用。 那在vue框架中&#xff0c;如果data中有一个变量:age&#xff0c;修改他&#xff0c;页面会自动更新。 但如果data中的变量为数组或对象&#xff0c;我们直接去给某个对象或数组添加属性&#xff0c;页面是识…