Python 核心技术与实战 --01 列表与元祖

2019-12-21

本文章主要讲述Python的列表元组

高级内容:

列表与元组存储方式的差异

了解 dir() 函数的概念:

   dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。

l = [1,3,3,4,8]
print(dir(l))

[‘__add__‘, ‘__class__‘, ‘__contains__‘,  \

‘__delattr__‘, ‘__delitem__‘, ‘__dir__‘,  \

‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, \

 ‘__getattribute__‘, ‘__getitem__‘, ‘__gt__‘, \

‘__hash__‘, ‘__iadd__‘, ‘__imul__‘, ‘__init__‘,\

 ‘__init_subclass__‘, ‘__iter__‘, ‘__le__‘, \

‘__len__‘, ‘__lt__‘, ‘__mul__‘, ‘__ne__‘, \

‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, \

‘__repr__‘, ‘__reversed__‘, ‘__rmul__‘, \

‘__setattr__‘, ‘__setitem__‘, ‘__sizeof__‘, \

‘__str__‘, ‘__subclasshook__‘, ‘append‘, ‘clear‘, \

‘copy‘, ‘count‘, ‘extend‘, ‘index‘, ‘insert‘, ‘pop‘, ‘remove‘, ‘reverse‘, ‘sort‘]
#list 的详细内容

l = [1,2,3]
print(l.__sizeof__())

64

tup =(1,2,3)
print(tup.__sizeof__())

48

列表和元组内的元素相同,但是 元组比列表少了 16 个字节, 为什么呢?

由于列表是动态的,所以它需要存储指针,来指向对应的元素(上述例子中,对于int类型,8个字节)。另外由于列表可变,所以需要额外存储已经分配的长度大小(8字节),这样才能实时追踪列表空间的使用情况,当空间不足时,及时分配额外空间。

可以看一下 python list  C 源码:

https://blog.csdn.net/qq_33339479/article/details/81807096

#define PyObject_VAR_HEAD      PyVarObject ob_base;
#define Py_INVALID_SIZE (Py_ssize_t)-1

/* Nothing is actually declared to be a PyObject, but every pointer to
 * a Python object can be cast to a PyObject*.  This is inheritance built
 * by hand.  Similarly every pointer to a variable-size Python object can,
 * in addition, be cast to PyVarObject*.
 */
typedef struct _object {
    _PyObject_HEAD_EXTRA
    Py_ssize_t ob_refcnt;                                       // 引用计数值
    struct _typeobject *ob_type;                                // 基本的类型 type
} PyObject;

typedef struct {
    PyObject ob_base;                                           // 对象基本信息
    Py_ssize_t ob_size; /* Number of items in variable part */  // 变长对象的元素个数
} PyVarObject;
...
typedef struct {
    PyObject_VAR_HEAD                                           // 变量头部信息
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;                                         // 元素指向具体指

    /* ob_item contains space for ‘allocated‘ elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     * list.sort() temporarily sets allocated to -1 to detect mutations.
     *
     * Items must normally not be NULL, except during construction when
     * the list is not yet visible outside the function that builds it.
     */
    Py_ssize_t allocated;                                       // 当前空间
} PyListObject;
l = []
print(l.__sizeof__())

l.append(1)
print(l.__sizeof__())

l.append(2)
print(l.__sizeof__())

40
72
72

列表的空间分配的过程可以看到,为了减小每次增加/删除的开销,python每次分配空间的时候都会多分配一点,这样的机制保证了其操作的高效性:增加/删除的时间复杂度均为O(1)

因为元组是静态的所以Python对于小量的静态内存就会放到缓存里面,下次分配同样多的元组时,就不用向操作系统发出请求了,就直接分配之前的缓存的内存空间。这样程序的运行速度就得到保证

初始化过程 python 3.7.0  列表优于元组(少量数据的时候)

C:\Users\qf>python -m timeit ‘x=(1,2,3,4,5,6)‘
20000000 loops, best of 5: 12.5 nsec per loop

C:\Users\qf>python -m timeit ‘x=[1,2,3,4,5,6]‘(少量数据的时候)
20000000 loops, best of 5: 12.2 nsec per loop
python 3.7.0   索引操作 列表 优于元组了
:\Users\qf>python -m timeit -s ‘x=[1,2,3,4,5,6]‘
0000000 loops, best of 5: 12.2 nsec per loop

:\Users\qf>python -m timeit -s ‘x=(1,2,3,4,5,6)‘
0000000 loops, best of 5: 13.7 nsec per loop

列表和元组的使用场景

1. 如果存储的数据和数量不变,比如你有一个函数,需要返回的是一个地点的经纬度,然后直接传给前端渲染,那么肯定选用元组更合适。

2.如果存储的数据或数量是可变的,比如社交平台上的一个日志功能,是统计一个用户在一周之内看了哪些用户的帖子,那么则用列表更合适

以下为基础内容:

1. 列表与元组基础

共同点: 列表和元组都是一个可以放置任意数据类型的有序集合。

不同点:1. 列表 是动态的,长度大小不固定,可以随意增加/删除 改变元素(mutable)

元组是静态的,长度大小固定,无法增加删减或者改变(immutable)

例子1:

1 # 列表的例子
2 l = [1, 2, 3, 4]
3 l[0] = 2
4 print(l)
[2, 2, 3, 4]
1 # 元组的例子
2 tup = (1, 2, 3, 4)
3 tup[0] = 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-77cf1f9285bd> in <module>
      1 # 元组的例子
      2 tup = (1, 2, 3, 4)
----> 3 tup[0] = 2
      4 

TypeError: ‘tuple‘ object does not support item assignment

但是你想对已有的元组做修改该怎么办呢?

答案:开辟一块新的内存,创建新的元组

# 元组和列表增加的例子
tup = (1, 2, 3, 4)
new_tup = tup + (5,)
print(new_tup)

l = [1,2,3,4]
l.append(5)
print(l)

执行结果:
(1, 2, 3, 4, 5)
[1, 2, 3, 4, 5]

2.列表和元组的索引

python 的列表和元组都支持负索引切片

列表和 元组支持任意嵌套

l = [[1,2,3],[4,5,6]]
tup =((1,2,3),(4,5,6))

通过 list() 和 tuple() 可以将两者相互转换.

3. 列表和元组常用的内置函数

(1) count()

# 元组和列表增加的例子
tup = (1, 2, 3, 4)
new_tup = tup + (5,)
print(new_tup.count(1))

l = [1,2,3,4]
l.append(5)
print(l.count(1))

执行结果
1
1

(2) index(item) 给出第一次出现的item 的索引

(3) list.reverse() 原地倒转列表 (元组没有)

l = [1,3,3,4,8]
l.append(5)
l.reverse()
print(l)

[5, 8, 4, 3, 3, 1]

(4) list.sort() 排序列表 (元组没有)

l = [1,3,3,4,8]
l.append(5)
l.reverse()
l.sort()
print(l)

[1, 3, 3, 4, 5, 8]

(5)reserved() 翻转后返回一个新的列表或元组

(6) sorted()排序后返回一个新的列表或元组

原文地址:https://www.cnblogs.com/qifei-liu/p/12076976.html

时间: 2024-07-30 21:03:44

Python 核心技术与实战 --01 列表与元祖的相关文章

列表和元祖

在python中,最基本的数据结构为序列.序列中的每个元素都有编号,即位置或索引.其中第一个元素的索引为0,第二个元素的索引为1,依次类推.从0开始指的是相对于序列开头的偏移量.用负索引表示序列末尾元素的位置. 序列概述 Python三种序列:列表.元祖.字符串. 列表和元祖的不同在于,列表是可以修改的,而元祖不可以.(想想为什么有的内置函数返回元祖的原因.) 在自己编写程序的时候,几乎所有的情况都可使用列表来代替元祖.一种情况例外,将元祖作用作字典键.(字典键是不允许修改的.) 列表用中括号来

Python核心技术与实战

课程目录:第00课.开篇词丨从工程的角度深入理解Python.rar第01课.如何逐步突破,成为Python高手?.rar第02课.Jupyter Notebook为什么是现代Python的必学技术?.rar第03课.列表和元组,到底用哪一个?.rar第04课.字典.集合,你真的了解吗?.rar第05课.深入浅出字符串.rar第06课.Python “黑箱”:输入与输出.rar第07课.修炼基本功:条件与循环.rar第08课.异常处理:如何提高程序的稳定性?.rar第09课.不可或缺的自定义函数

python学习第二周(数据类型、字符串、列表、元祖、字典)

一.模块.库 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,几乎你想实现的任何功能都有相应的Python库支持. 模块初始化:模块就是库,库可以是标准库或者是第三方库. sys模块 os模块 Sys.path 导入模块的时候,先从当前目录下面查找. 我们起名字时候不能和导入的模块名字相同. Python的第三方库 E:\\python_path\\base\\lib\\site-packages Python的标准库位置 E:\\python_path\\base Sys.ar

Python笔记_01列表 和元祖

Python笔记 第一章 列表和元祖 1.通用序列操作 所有序列都可以进行某些特定操作,包括:索引(indexing).分片(slicing).加(adding).乘(multiplying)以及检查某元素是否属于列表成员. 迭代:依次对序列中的每个元素重复执行某些操作. 序列的索引:通过元素在列表中的位置可以定位到该元素,这就是列表的索引,使用类似于list[0]对元素进行索引,索引0指向第一个元素.也可使用负数对元素进行索引,使用负数对元素索引时,列表中的最后一个元素由-1表示,例如list

what&#39;s the python之基本运算符及字符串、列表、元祖、集合、字典的内置方法

计算机可以进行的运算有很多种,运算按种类可分为算数运算.比较运算.逻辑运算.赋值运算.成员运算.身份运算.字符串和列表的算数运算只能用+和*,字典没有顺序,所以不能进行算数运算和比较运算.比较运算中==比较的是值,is比较的是id.比较运算只能在同种类型下进行比较.字符串的比较是按照顺序依次进行比较.逻辑运算的顺序先后为要用括号来表示. 基本运算符如下: 算术运算 以下假设a=10,b=20 比较运算 以下假设a=10,b=20 赋值运算 逻辑运算  成员运算 身份运算 what's the 内

python系列之列表和元祖

容器: 列表和元祖 区别: 列表可以修改,而元祖不能 序列:列表,元祖(序列中每个元素都有自己的id(编号),编号从0开始往右递增) 共性: 索引: eg:name='Jack',name[0]='J' 注:也可以直接'Jack'[0]='J' 分片: 提供两个索引作为边界,第一个索引的元素包含在分片内,而第二个则不包含在分片内. eg:numbers=[0,1,2,3,4,5,6,7,8,9],则numbers[0:3]=[0,1,2] 捷径:numbers[:]就等于整个序列 步长:eg:n

Python基础-列表、元祖、字典、字符串

列表和分组 序列概览: 数据结构是通过某种方式组织在一起的数据元素的集合.这些元素可以是数字.字符,甚至可以是其他数据结构. 在python中,最基本的数据结构是序列(sequence). 序列中的每一个元素被分配一个序号----即元素的位置,也称为索引.下标.第一个索引是0,第二个索引是1,以此类推. Python包含6种内建的序列,此次重点讨论最常用的两种类型:列表.元祖.其他内建序列类型包括:字符串.Unicode字符串.buffer对象和xrange对象.接下来讲解对所有序列都通用的操作

Python编程从入门到实践(第三、四章的列表和元祖) &#142015;

原文: http://blog.gqylpy.com/gqy/414 置顶:来自一名75后老程序员的武林秘籍--必读(博主推荐) 来,先呈上武林秘籍链接:http://blog.gqylpy.com/gqy/401/ 你好,我是一名极客!一个 75 后的老工程师! 我将花两分钟,表述清楚我让你读这段文字的目的! 如果你看过武侠小说,你可以把这个经历理解为,你失足落入一个山洞遇到了一位垂暮的老者!而这位老者打算传你一套武功秘籍! 没错,我就是这个老者! 干研发 20 多年了!我也年轻过,奋斗过!我

python基础--列表、元祖、字典、集合

列表(List) 1.列表特点 列表是可变的!! list 是一种有序的序列,可以添加.删除其中的元素,并且可以通过下标(索引)访问 数据 2.简单的常用操作 A.通过下表访问元素 1 print(list1[0]) ##正序 2 print(list1[-1]) ##倒序 3 5 list[0] = '123' ##修改指定位置的值 B.切片 1 print(list[1:3]) 3.常用操作: 1 ##append:追加元素 2 list1.append('赵四') 3 4 ##extend