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

     

     
  • 相关阅读:
    java实现按对象某个字段排序,排序字段和规则自定义
    JVM调优
    Spring事务的5种隔离级别
    Spring的七种事务传播机制
    jdk动态代理和cglib动态代理的区别
    spring事务的开启方式(编程式和声明式)
    jetty启动(server-connector-handle-start-join)
    浅谈background-size的几个属性值
    如何解决各类尺寸移动端自适应的问题?
    如何实现一个盒子看起来缓慢消失切换到另一个页面的效果?
  • 原文地址:https://www.cnblogs.com/hujingnb/p/11914907.html
Copyright © 2020-2023  润新知