Python核心技术与实战
景霄
Facebook资深工程师
立即订阅
13891 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 从工程的角度深入理解Python
免费
基础篇 (14讲)
01 | 如何逐步突破,成为Python高手?
02 | Jupyter Notebook为什么是现代Python的必学技术?
03 | 列表和元组,到底用哪一个?
04 | 字典、集合,你真的了解吗?
05 | 深入浅出字符串
06 | Python “黑箱”:输入与输出
07 | 修炼基本功:条件与循环
08 | 异常处理:如何提高程序的稳定性?
09 | 不可或缺的自定义函数
10 | 简约不简单的匿名函数
11 | 面向对象(上):从生活中的类比说起
12 | 面向对象(下):如何实现一个搜索引擎?
13 | 搭建积木:Python 模块化
14 | 答疑(一):列表和元组的内部实现是怎样的?
进阶篇 (11讲)
15 | Python对象的比较、拷贝
16 | 值传递,引用传递or其他,Python里参数是如何传递的?
17 | 强大的装饰器
18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?
19 | 深入理解迭代器和生成器
20 | 揭秘 Python 协程
21 | Python并发编程之Futures
22 | 并发编程之Asyncio
23 | 你真的懂Python GIL(全局解释器锁)吗?
24 | 带你解析 Python 垃圾回收机制
25 | 答疑(二):GIL与多线程是什么关系呢?
规范篇 (7讲)
26 | 活都来不及干了,还有空注意代码风格?!
27 | 学会合理分解代码,提高代码可读性
28 | 如何合理利用assert?
29 | 巧用上下文管理器和With语句精简代码
30 | 真的有必要写单元测试吗?
31 | pdb & cProfile:调试和性能分析的法宝
32 | 答疑(三):如何选择合适的异常处理方式?
量化交易实战篇 (8讲)
33 | 带你初探量化世界
免费
34 | RESTful & Socket: 搭建交易执行层核心
35 | RESTful & Socket: 行情数据对接和抓取
36 | Pandas & Numpy: 策略与回测系统
免费
37 | Kafka & ZMQ:自动化交易流水线
38 | MySQL:日志和数据存储系统
39 | Django:搭建监控平台
40 | 总结:Python中的数据结构与算法全景
技术见闻与分享 (4讲)
41 | 硅谷一线互联网公司的工作体验
42 | 细数技术研发的注意事项
加餐 | 带你上手SWIG:一份清晰好用的SWIG编程实践指南
43 | Q&A:聊一聊职业发展和选择
结束语 (1讲)
结束语 | 技术之外的几点成长建议
Python核心技术与实战
登录|注册

03 | 列表和元组,到底用哪一个?

景霄 2019-05-15
你好,我是景霄。
前面的课程,我们讲解了 Python 语言的学习方法,并且带你了解了 Python 必知的常用工具——Jupyter。那么从这节课开始,我们将正式学习 Python 的具体知识。
对于每一门编程语言来说,数据结构都是其根基。了解掌握 Python 的基本数据结构,对于学好这门语言至关重要。今天我们就一起来学习,Python 中最常见的两种数据结构:列表(list)和元组(tuple)。

列表和元组基础

首先,我们需要弄清楚最基本的概念,什么是列表和元组呢?
实际上,列表和元组,都是一个可以放置任意数据类型的有序集合
在绝大多数编程语言中,集合的数据类型必须一致。不过,对于 Python 的列表和元组来说,并无此要求:
l = [1, 2, 'hello', 'world'] # 列表中同时含有intstring类型的元素
l
[1, 2, 'hello', 'world']
tup = ('jason', 22) # 元组中同时含有intstring类型的元素
tup
('jason', 22)
其次,我们必须掌握它们的区别。
列表是动态的,长度大小不固定,可以随意地增加、删减或者改变元素(mutable)。
而元组是静态的,长度大小固定,无法增加删减或者改变(immutable)。
下面的例子中,我们分别创建了一个列表与元组。你可以看到,对于列表,我们可以很轻松地让其最后一个元素,由 4 变为 40;但是,如果你对元组采取相同的操作,Python 就会报错,原因就是元组是不可变的。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Python核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(159)

  • 胡峣
    老师能不能讲一下list和tuple的内部实现,里边是linked list 还是array,还是把array linked一下这种。
    最后那个问题,类比java,new 是在heap,直接声明就可能在常量区了。老师能讲下Python的vm么,比如内存分配,gc算法之类的。

    作者回复: 1. list和tuple的内部实现都是array的形式,list因为可变,所以是一个over-allocate的array,tuple因为不可变,所以长度大小固定。具体可以参照源码list: https://github.com/python/cpython/blob/master/Objects/listobject.c. tuple: https://github.com/python/cpython/blob/master/Objects/tupleobject.c

    2. 最后的思考题:
    区别主要在于list()是一个function call,Python的function call会创建stack,并且进行一系列参数检查的操作,比较expensive,反观[]是一个内置的C函数,可以直接被调用,因此效率高。
    内存分配,GC等等知识会在第二章进阶里面专门讲到。

    2019-05-15
    100
  • Python高效编程
    元素不需要改变时:
    两三个元素,使用 tuple,元素多一点使用namedtuple。
    元素需要改变时:
    需要高效随机读取,使用list。需要关键字高效查找,采用 dict。去重,使用 set。大型数据节省空间,使用标准库 array。大型数据高效操作,使用 numpy.array。
    2019-05-15
    81
  • 看,有只猪
    []比list()更快,因为调用list函数有一定的开销,而[]却没有。
    这个有点像C语言中的内联函数与函数的差异
    2019-05-15
    68
  • adapt
    如果一个列表在元组中的话,其实这个元组是”可变”的,只是这个可变只是能改变该列表里的内容。 这一点作者没有讲到哦 。
    2019-05-15
    2
    35
  • converse✪
    针对可以随意嵌套进行总结:

    - 列表嵌套列表:本质是列表,内部列表和外部列表的内容可以进行修改元素,插入,删除元素。也就是二维数组。
    - 列表嵌套元组:本质是列表,所以可以对列表中除元组外的其他元素可以修改插入、删除。但元组中的内容不可以改变。
    - 元组嵌套列表:本质是元组,元组中的任何元素不能进行改变,但是对于元素本身是列表的情况,可以对列表中的值进行修改。这是因为:列表对象是不变的,只是的列表中的内容进行变化。列表本来就是动态的。
    - 元组嵌套元组:本质元组,元组中的元素还是元组。所以这种情况下,不能进行任何改变。也就是不可变的二维数组。
    2019-05-17
    26
  • DUDUANWANGGU198.com
    老师请问一下,为什么l = [1, 2, 3]消耗的空间为64字节,而l.append(1), l.append(2), l.append(3)消耗的空间为72字节,这不是相同的列表吗?

    作者回复: 列表的over-allocate是在你加入了新元素之后解释器判断得出当前存储空间不够,给你分配额外的空间,因此
    l=[], l.append(1), l.append(2), l.append(3)实际分配了4个元素的空间。但是l=[1, 2, 3]直接初始化列表,并没有增加元素的操作,因此只会分配3个元素的空间

    2019-05-15
    22
  • 对方正在输入中…
    python -m timeit 'empty_list = list()'
    10000000 loops, best of 3: 0.0829 usec per loop

    python -m timeit 'empty_list = []'
    10000000 loops, best of 3: 0.0218 usec per loop

    python -m timeit 'empty_list = ()'
    100000000 loops, best of 3: 0.0126 usec per loop
    测试结果,虽然直接创建元组初始化速度最快,但是由于要用list函数转一道反而不如直接创建列表的速度快。
    2019-05-15
    20
  • converse✪
    空list在申请空间时候,是40字节。当加入新元素后会额外多分配空间变成72字节。当加入4个元素后还是72字节。那么问题来了,初始化申请的40字节是什么?感觉一直没有用到?不是用于存储元素的么?
    2019-05-17
    2
    18
  • Geek_59f23e
    1、用list()方法构造一个空列表使用的是class list([iterable])的类型构造器,参数可以是一个iterable,如果没有给出参数,构造器将创建一个空列表[ ],相比较而言多了一步class调用和参数判断,所以用 [ ] 直接构造一个空列表的方法速度更快,刚查的官方解释,不知道我理解的对不对。。。
    2、敲代码的时候我一般元祖用来传参用的比较多,能用元祖的地方尽量不用列表,这样代码性能好些。

    作者回复: 1. 区别主要在于list()是一个function call,Python的function call会创建stack,并且进行一系列参数检查的操作,比较expensive,反观[]是一个内置的C函数,可以直接被调用,因此效率高

    2. 嗯嗯

    2019-05-15
    14
  • 汤尼房
    景老师,一直在想一个tuple元组如何拥有大数据量的元素,比如千万个元素、上亿个元素。因为tuple是静态的,不能添加元素,于是今天实践将[i for i in xrange(1000000000)]给初始化成tuple,发现初始化的过程相当耗时间,之前也希望利用tuple的性能比list好的优点,想把含有大数据量的list给转换成tuple来处理,今天实践发现初始化过程非常耗时间,请问景老师,平时在工作过程中遇到的含有大数据量个元素的tuple是如何形成的呢?
    2019-05-15
    7
  • 高权
    为什么我测试的元组和列表的初始化时间一样呢?
    2019-05-23
    6
  • kevinsu
    import timeit
    print(timeit.timeit('list(x for x in range(1,1000))',number=10000))
    print(timeit.timeit('[x for x in range(1,1000)]',number=10000))
    0.6829426919994148
    0.36637431800045306
    看着是[]更快些,😄
    2019-05-15
    2
    5
  • Jared
    老师真帅。
    2019-05-15
    5
  • Geek_59f23e
    实测被打脸了😂函数构建和直接构建一个空列表或数组速度上并没有什么差别,有时前者快些,有时后者快些。。。

    In [1]: timeit 'lst1 = []'
    9.86 ns ± 0.721 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

    In [2]: timeit 'lst2 = list()'
    9.82 ns ± 0.43 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

    In [3]: timeit 'tup1 = (,)'
    9.59 ns ± 0.294 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

    In [4]: timeit 'tup2 = tuple()'
    9.75 ns ± 0.464 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

    作者回复: 你的命令有些奇怪。在程序里也应该是timeit(...),试过用文中的命令测试的结果吗?

    另外你python的版本和运行环境的截图能贴一下吗?

    2019-05-15
    2
    5
  • ........
    1. 测试了一下, []快于list()
    2. 一般在key中使用元祖,其他情况多数都使用列表
    2019-05-15
    5
  • 許敲敲
    思考题 试了运行timeit,发现在我电脑上两个创建列表的时间一样,所以答案是什么呢?
    2019-05-15
    4
  • 播州新府
    []比list()更快,因为调用list函数有一定的开销,而[]却没有。
    这个有点像C语言中的内联函数与函数的差异(from 看 有只猪)
    2019-08-28
    3
  • 小豹子
    之前用list,dict,set,tuple,都是只知道这是什么类型,怎么用,从来也没有想过这些数据结构是如何存储的,突然想搞明白这些事的时候,网上却很难找到有意义的文章,老师能推荐相关书籍吗?
    2019-05-26
    3
  • 刘朋
    import timeit
    timeit.timeit('a=list()',number=10000) 返回 0.0006914390251040459
    timeit.timeit('a=[]',number=10000) 返回 0.00018375739455223083
    timeit.timeit('a=()',number=10000) 返回 0.00010870955884456635
    2019-05-15
    3
  • kevinsu
    可以这样比较吗?老师
    import time
    time1 = time.clock()
    empty_list = list()
    time2 = time.clock()
    diff_time = time2 - time1
    print (diff_time)

    import time
    time1 = time.clock()
    empty_list = []
    time2 = time.clock()
    diff_time = time2 - time1
    print (diff_time)

    作者回复: 这样可以,但是不是很准确,尤其对于简单并且运行速度很快的代码块,建议用timeit。
    因为程序中还有很多因素会影响计算的时间,比如垃圾回收机制。使用timeit会自动关掉垃圾回收机制,让程序的运行更加独立,时间计算更加准确。

    2019-05-15
    3
收起评论
99+
返回
顶部