专栏首页烟草的香味Python元组是什么

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 getsizeofif __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, 3if __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的元素给我。在此,意会一下。

本文分享自微信公众号 - 烟草的香味(hujing-bc),作者:胡靖哥哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java集合之LinkedHashMap源码分析

    LinkedHashMap是HashMap的一个子类, 它通过重写父类的相关方法, 实现自己的功能. 它保留插入的顺序. 如果需要输出和输入顺序相同时, 就选用...

    烟草的香味
  • 设计模式之空对象模式

    空对象模式是通过实现一个默认的无意义对象来避免null值出现, 简单地说,就是为了避免在程序中出现null值判断而诞生的一种常用设计方法.

    烟草的香味
  • Java集合之HashSet源码分析

    HashSet是基于HashMap来实现的, 底层采用HashMap的key来保存数据, 借此实现元素不重复, 因此HashSet的实现比较简单, 基本上的都是...

    烟草的香味
  • Java奇淫巧技之Lombok

    背景   我们在开发过程中,通常都会定义大量的JavaBean,然后通过IDE去生成其属性的构造器、getter、setter、equals、hashcode、...

    高爽
  • 前端学习笔记之CSS浮动浅析

           很早以前就接触过CSS,但对于浮动始终非常迷惑,可能是自身理解能力差,也可能是没能遇到一篇通俗的教程。

    Jetpropelledsnake21
  • Excel界地震 微软宣布 跨4代人34岁的 VLOOKUP 退休

    只要你在工作,几乎就不会用不到Excel;只要你用Excel,几乎就不会用不到 VLOOKUP 这个函数。VLOOKUP 的作用在于查找,这在数据处理中是一个非...

    Python进阶者
  • Excel界地震 微软宣布 跨4代人34岁的 VLOOKUP 退休

    只要你在工作,几乎就不会用不到Excel;只要你用Excel,几乎就不会用不到 VLOOKUP 这个函数。VLOOKUP 的作用在于查找,这在数据处理中是一个非...

    用户6070864
  • JavaScript语言精粹【语法、对象、函数】

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

    奋飛
  • 浏览器相关--H5本地存储

    浏览器存储主要包括一下几个部分 1. cookie 2. localStorage 3. sessionStorage 4. indexDB 5. websql...

    木子墨
  • 直接在主机操作容器网络namespace并添加veth

    此时执行ifconfig,可以明确的看到显示的IP不是主机的IP,而是这个容器的IP 172.17.0.2。如果想设置一些其它的东西,那就很开心了。

    超级大猪

扫码关注云+社区

领取腾讯云代金券