Python元组是什么

 

引出

在使用Python过程中,列表、集合和字典是比较常用的数据结构。

  • 列表简单说就是数组,不对,它就是数组

  • 集合就是去重的元素结构,和JAVA中的set一样

  • 字典就是一个key-value的键值对,和JAVA中的HashTable一样

但是,Python中有一个特立独行的对象,元组tuple,看一个元组的简单使用:

tu = (2, 3)
a = tu[0] # a=2
b = tu[1] # b=3

什么?你告诉我这个一个新的结构?不是数组???

这用起来跟数组也没什么区别啊?

要看元组和数组的区别,最直观的比较,就是比较两个结构的方法,通过方法来理解结果。

方法比较

列表用的比较多了,方法基本上都是常规的数组操作:对数组的增删改查。对了,还有Python列表最屌的操作,数组的切片操作。

(悄悄告诉你,查看方法只要Python运行 help(list), 就可以了)

再看一下元组的方法,暴露出来的方法只有两个,countindex

  • count(x): 统计x在元组中的个数

  • index(x): 返回x在元组中第一次出现的索引

恩,我知道区别了,元组只能查,不能做增删改的操作。

只能查询,不可修改,这不是常量么。。。。既然是常量,想必虚拟机内部会做优化,元组占用的空间会比列表少很多吧。

内存比较

分别定义列表和元组,查看其内存占用情况:

from sys import getsizeof
​
if __name__ == '__main__':tu = (x for x in range(20000))li = [x for x in range(20000)]print(getsizeof(tu))print(getsizeof(li))

输出结果:

啥?元组这么小么?我两万个数字才占用88个字节?我不服,再怎么优化这也不可能,它不是元组:

if __name__ == '__main__':tu = (x for x in range(20000))li = [x for x in range(20000)]print(type(tu))print(type(li))

哦哦,不好意思啊,走错片场了,这是个生成器。重新来过:

from sys import getsizeof
​
if __name__ == '__main__':tu = tuple(x for x in range(20000))li = list(x for x in range(20000))print(type(tu))print(getsizeof(tu))print(type(li))print(getsizeof(li))

这回没毛病了,元组确实比列表占用空间要少一些。

至此,基本已经确定了,元组最大的特性就是不可变。

通过元组的不可变特性,引申出了很多数组无法实现的功能

这里,看到网上有人说元组中的数组是可变的,也给出了对应的解释。简单说,元组中保存的是数组的地址,尽管数组内容变了,但地址没有变,也就是元组内容没有发生变化,很好理解。

元组的灵活使用

  1. 元组是可以计算hash值的,这也就意味元组可以当做hashTable中的key存在

if __name__ == '__main__':tu = tuple(x for x in range(20000))li = list(x for x in range(20000))print(hash(tu))print(hash(li))

有人说,字符串就足够了,没必要用元组。恩?我想到一个应用场景:

如果要通过用户的信息(身高,体重,性别)来查找用户的id,我们固然可以遍历一遍用户,将符合条件的筛选出来。但这样太慢了,如果我们维护一个用户信息为key,值为id数组的hashMap,那查找就十份快速了。

当然,使用字符串也完全可以满足,将用户的各种信息拼接起来,但使用元组显然更加直观,key直接就是(身高,体重,性别)。

  1. 这个虽然和元组的不可变没什么关联,但同样十分实用。实现函数返回多个值。

def test_fun():return 2, 3
​
if __name__ == '__main__':a, b = test_fun()# 用*来接受剩余的内容d, *other = test_fun()re = test_fun()print(a, b)print(re)print(type(re))

妈妈再也不用担心我的函数返回了。

站在巨人的肩膀上

通过先人的成果来理解列表和元组,下面以numpy为例,通过作者对二者的理解来帮助我理解。

import numpy
​
if __name__ == '__main__':# 创建一个二维数组a = numpy.arange(9).reshape(3, 3)print(a)tu = (1, 2)li = [1, 2]print(a[tu])print(a[li])

显然,使用元组访问时,它接收到的意图是:我想要下标为1的数组中下标为2的元素。而使用数组访问时,它收到的意图是:请把下标为1和下标为2的元素给我。在此,意会一下。

 

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

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

相关文章

B+树

引言 时隔一年,我又想起当初看数据库时,看到的B树,就是数据库的索引使用的数据结构。再整理一下,看看自己没有忘记很多吧。 概述 B树之前,先来看一下二叉查找树(1,2,3,4,5,6,7) 恩&#xff0…

Python导入运行的当前模块报错

引言 今天遇到了一个奇怪的现象,简单举个栗子: 文件结构如下: 其中tt.py文件中定义了一个方法: def tt():print(tt) 我现在要在test.py中使用tt(), 代码如下: from test.tt import tt ​ if __name__ __main__:t…

Python中的+=

引出 今天在运行之前写的一个Python脚本时,发生了一个奇怪的现象(我怎么老遇到奇怪的现象~~)。当时的代码大概长这样: a [1, 2, 3] b [4, 5, 6] # ...一大段逻辑 c a c b # ...一大段逻辑 # 在这里&a…

js new Date 创建时间默认是8点

起因 最近在写一个页面,需要用到时间控制。然后我通过new Date()传入日期字符串创建了一个对象,并与当前时间做时间戳比较,结果12点刚过,就出问题了。举个栗子: // 假设当前时间是2019年12月22日0点20分 new Date(20…

Ubuntu14升级MySQL

最近需要将测试环境的MySQL从5.6升级到5.7. 我就自己先虚拟机搭了一个Ubuntu14进行模拟升级, 不得了 开始了各种踩坑记录 方案一 此方案可以跳过, 全是坑. 搜索 Ubuntu14 MySQL升级5.7, 出现很多结果 查看后发现处理方法全都一样, 既然大家都是这么升级的, 肯定么得问题. …

微信朋友圈技术实现设想

前提 微信朋友圈是我们每天都在用的功能, 但是如果让你来实现一个微信朋友圈, 你会如何做呢? 我来简单设想一下. 实现功能 发朋友圈评论动态查看朋友圈(只能查看好友的)查看评论(只能查看共同好友的) 是不是看着很简单? 也没有几个功能嘛. so easy. 开始实现 数据库选用…

redis的多路复用是什么鬼

有没有人和我一样, 自打知道了redis, 就一直听说什么redis单线程, 使用了多路复用等等. 天真的我以为多路复用是redis实现的技术. 今天才发现, 我被自己骗了, 多路复用是系统来实现的. 对不起自己的专业了. 为了引出多路复用, 我来大胆设想一下技术的发展路程. 前提 一个应用…

WebSocket小叙

概述 刚看到WeSocket的时候,我以为是HTTP相关,但是在前两天搭了一个简单的Client之后, 我发现这不就是TCP长连接么? 建立连接->通信->断开连接. 直到今天, 我在调试的时候, 发现发出了HTTP请求, 我想, 事情可能不是我想的那样. 先来简单描述一下…

PHP实现RPC(简版)

概述 RPC这个东西是什么? 第一次听说他, 还要在它的前边加个G, 当时我以为GRPC是一项技术, 后来才知道, 并不是这样. GRPC只是RPC的谷歌实现. 谷歌搜了一下, RPC就是一种: 远程函数调用, 看到这里, 我已经等不及了, 不往下看了, 先自己实现一个. 如果只给你这样一个概念, 如…

GC算法-复制算法

概述 复制算法就是将内存空间二等分, 每次只使用其中一块. 当执行GC时, 讲A部分的所有活动对象集体移到B中, 就可以讲A全部释放. 画个图就是: ​ 在执行GC前, 内存长这样: ​ 当执行GC后, 内存就变成这样了: 还记得标记清除算法的问题是什么吗? 内存碎片化严重. 现在好了, …

GC算法-标记压缩算法

概述 还记得标记清除和复制算法的问题么? 堆使用效率低和碎片化问题. 那么有没有能够利用整个堆, 有没有内存碎片化问题的算法呢? 这就是标记压缩算法了. 简单来说, 标记压缩算法就是将堆中的所有活动对象整体向左移, 将对象间的空隙消除. 在GC执行前的内存: GC执行后的内…

PHP usort 函数底层排序

引出 最近在一个项目中, 需要对一个数组的顺序进行调整, 允许手动将某一个元素提到数组的开头位置. 在这里, 使用了PHP中的usort函数进行了数组的排序, 代码大致如下: usort($arr, function ($a, $b){// 这里添加了 order 字段, 默认为0, 将order大的提到前边return $b[order…

密钥交换算法: 迪菲-赫尔曼算法

概述 迪菲-赫尔曼算法用于通信双方交换密钥. 还记得之前介绍HTTPS协议的时候, 提到需要先通过对方公钥来进行密钥的交换, 然后再通过密钥对通信内容进行加密. 迪菲-赫尔曼算法就是用于交换密钥的. . 此算法与非对称加密算法不同哦. OK, 一起来看看吧. 引入 在正式介绍迪菲-…

纠错码简介

纠错码是个什么东西 引出 网络中的通信基于TCP和UDP两个通信协议, 这大家都知道的, 什么TCP的三次握手等等, 面试经常被问到. 三次握手是为了保证连接的正确建立. 但是, 在通信的时候, 你如何保证你的消息正确送达了呢? 有人说了, 有收到请求的响应包. 但我说的不是这个, 比…

计算机全加器简单实现

概述 用了这么久计算机, 都知道计算机有一个核心部件叫 CPU, 而 CPU中有一个小部件叫做全加器. 它是用来做什么的呢? 看名字就知道了, 做加法运算用的. 那么如何实现一个全加器呢? 你以为这又是一篇计算机内部原理的文章? 不, 放开那个女孩, 和我一起走进中学物理的课堂. …

TCP 三次握手的意义

概述 在网络的传输层协议中, 存在着两大悍将: TCP 和 UDP . 从前, 我傻傻的以为自己对他们虽谈不上精通, 但还是知道的, 但是, 我错了, 我被自己问住了, 我傻了. 啥也不是. UDP (这里为了介绍简单, 就不提数据在传输过程中的失真(纠错码)等情况了. 简单介绍一下, TCP才是今天…

GO 文档笔记

前言 最开始写 GO 的时候, 发现方法的注释并不支持param, return等参数, 搞得我都不知道该如何给自己的方法写文档说明了. 而且网上搜了搜也没有搜到教程, 甚是郁闷. 今天找到了GO内置的文档工具: godoc. (我用的1.14.3版本貌似不是自带工具了, 需要安装(配置代理): go get g…

有了 elseif 为什么还要 switch case

引出 你有没有想过既然有了if elseif, 为什么还要设计一个switch case的语法出来呢? 按理说, 一个语言的设计角度来说, 关键词越少越好吧, 而且多出来一种选择分支也没有看出太大用处. 以下几种switch case均可以写成if else的形式(java 代码): // 形式一 switch(a){case 1:…

计算矩阵中全1子矩阵的个数

前言 最近被我大哥安利了一道算法题, 这道题说难, 还不至于我做不出来, 说简单吧, 我还想不到最优解, 等把最优解告诉我之后, 我还正好能理解. 我甚至曾经怯怯的认为, 这题就是我哥专门给我找的, 嘿嘿, 心中说不出的小欢喜. 题来了, 此题出自力扣, 原题链接: https://leetco…

搭建本地 HTTPS 环境

前言 之前写自己的网站时, 申请过免费的https证书. 最近想在自己本地搭一个, 结果忘了当初证书是怎么来的了. 本来想着去申请个免费的证书, 但想了想, 我只需要在自己本地能使用就行了, 我自己的环境, 那当然是我说了算了. 只要能够将证书构造出来, 安装到本地就可以识别了. 搜…