学习Python列表的基础知识汇总


Posted in Python onMarch 10, 2020

千里之行,始于足下。要练成一双洞悉一切的眼睛,还是得先把基本功扎扎实实地学好。今天,本喵带大家仔细温习一下Python的列表。温故而知新,不亦说乎。

当然,温习的同时也要发散思考,因为有些看似无关紧要的、约定俗成的语言习惯,例如数组索引为何从0开始,其背后可能大有来历。知其然,亦需知其所以然啊喵喵喵~~~

最后,在基础知识之上,更要探索进阶,例如学习生成器表达式,这样既能更扎实地掌握基础,又能融会贯通,获得更全面的认知升级。

Python的列表是怎样滴?

列表(list)是一种有序的集合,可以随时添加、查找和删除元素。

列表支持加入不同数据类型的元素:数字、字符串、列表、元组等。

列表通过有序的索引可遍历所有的元素,从前往后数,索引是[0,n-1],从后往前数,索引是[-1, -n],其中n是列表的长度。

列表可以是不含元素的空列表,也可以包含超级多的元素(在内存大小支持的情况下)。

list_a = []  # 空列表,即len(list_a) == 0
list_b = [2018, 10, '2018-10-1', ['hi', 1, 2], (33, 44)]

# list_b 长度为5,包含2个数字元素、1个字符串元素、1个列表元素和1个元组元素
len(list_b) == 5
list_b[0] == list_b[-5] == 2018
lits_b[3] == list_b[-2] == ['hi', 1, 2] 
lits_b[4] == list_b[-1] == (33, 44)

Python中怎么操作列表?

1)创建列表:

用中括号[]包裹元素,元素使用逗号分隔。

用list()方法,转化生成列表。

列表生成式/列表解析式/列表推导式,生成列表。

list_a = [1, 2, 3]
list_b = list("abc") # list_b == ['a', 'b', 'c']
list_c = list((4, 5, 6)) # list_c == [4, 5, 6]
list_d = [i for i in list_a] # list_d == [1, 2, 3]
list_e = [i*j for i in list_a for j in list_c] # list_e == [4,5,6,10,12,12,15,18]
list_f = [i*j for i,j in zip(list_a,list_c)] # list_f == [4, 10, 18]
list_g = [i for i in list_a if i%2 == 0] # list_g == [2]

# 结合range()函数,range(start, stop[, step])
list_h = list(range(3)) # list_h == [0, 1, 2]
list_i = list(range(3,7)) # list_i == [3, 4, 5, 6]
list_j = list(range(3,9,2)) # list_j == [3, 5, 7]

# 找出100以内的能够被3整除的正整数
list_k = list(range(3,100,3)) # list_k == [3, 6, 9, ..., 96, 99]

2)扩充列表:

用append()方法,在列表尾部添加单个新元素。

用insert()方法,在列表中指定位置添加元素。

用 “+” 运算符,将两个列表拼接出一个新列表。

用extend()方法,在一个列表后面拼接进另一个列表。

# 以下分别添加2个元素
list_a = []
list_a.append('happy') # list_a == ['happy']
list_a.insert(0, 'very') # list_a == ['very', 'happy']

# 以下两种扩充列表方式
list_1 = ['I', 'am']
list_2 = ['very', 'happy']
list_3 = list_1 + list_2 # 新列表 list_3 == ['I', 'am', 'very', 'happy']
list_1.extend(list_2) # 原列表1扩充,list_1 == ['I', 'am', 'very', 'happy']

3)删减列表与销毁列表:

用del list[m] 语句,删除指定索引m处的元素。

用remove()方法,删除指定值的元素(第一个匹配项)。

用pop()方法,取出并删除列表末尾的单个元素。

用pop(m)方法,取出并删除索引值为m的元素。

用clear()方法,清空列表的元素。(杯子还在,水倒空了)

用del list 语句,销毁整个列表。(杯子和水都没有了)

# 以下4种删除列表元素方式
list_1 = list_2 = list_3 = list_4 = ['I', 'am', 'very', 'happy']
del list_1[0] # list_1 == ['am', 'very', 'happy']
list_2.remove('I') # list_2 == ['am', 'very', 'happy']
list_3.pop() # list_3 == ['I', 'am', 'very']
list_4.pop(0) # list_4 == ['am', 'very', 'happy']

# 清空与销毁
list_a = [1, 2, 3]
list_b = [1, 2, 3]
list_b.clear()  # list_b == []
del list_a  # 没有list_a了,再使用则会报错

4)列表切片:

基本含义:从第i位索引起,向右取到后n位元素为止,按m间隔过滤

基本格式:[i : i+n : m] ;i 是切片的起始索引值,为列表首位时可省略;i+n 是切片的结束位置,为列表末位时可省略;m 可以不提供,默认值是1,不允许为0,当m为负数时,列表翻转。注意:这些值都可以大于列表长度,不会报越界。

li = [1, 4, 5, 6, 7, 9, 11, 14, 16]

# 以下写法都可以表示整个列表,其中 X >= len(li)
li[0:X] == li[0:] == li[:X] == li[:] == li[::] == li[-X:X] == li[-X:]

li[1:5] == [4,5,6,7] # 从1起,取5-1位元素
li[1:5:2] == [4,6] # 从1起,取5-1位元素,按2间隔过滤
li[-1:] == [16] # 取倒数第一个元素
li[-4:-2] == [9, 11] # 从倒数第四起,取-2-(-4)=2位元素
li[:-2] == li[-len(li):-2] == [1,4,5,6,7,9,11] # 从头开始,取-2-(-len(li))=7位元素

# 注意列表先翻转,再截取
li[::-1] == [16,14,11,9,7,6,5,4,1] # 翻转整个列表
li[::-2] == [16,11,7,5,1] # 翻转整个列表,再按2间隔过滤
li[:-5:-1] == [16,14,11,9] # 翻转整个列表,取-5-(-len(li))=4位元素
li[:-5:-3] == [16,9] # 翻转整个列表,取-5-(-len(li))=4位元素,再按3间隔过滤

li[::0] # 报错(ValueError: slice step cannot be zero)

5) 其它操作:

用len()方法,统计全部元素的个数。

用count()方法,统计指定值的元素的个数。

用max()方法,统计元素中的最大值(要求元素类型相同;数字类型直接比较,其它类型比较id)

用min()方法,统计元素中的最小值(要求元素类型相同;数字类型直接比较,其它类型比较id)

用index()方法,查找指定值的元素的索引位置(第一个匹配项)。

用reverse()方法,翻转列表中的元素。

用copy()方法,浅拷贝并生成新的列表。

用deepcopy()方法,深拷贝并生成新的列表。

用sort()方法,在原列表基础上进行排序。

用sorted()方法,将新列表基础上对原列表的元素进行排序。

list_1 = [2018, 10, '2018-10-1', ['hi', 1, 2], (33, 44)]
len(list_1) == 5
list_1.count(10) == 1 # 元素10的数量为1
list_1.index(10) == 1 # 元素10的索引为1
list_1.reverse() # list_1 == [(33, 44), ['hi', 1, 2], '2018-10-1', 10, 2018]

# 比较浅拷贝与深拷贝
import copy
list_a = [2018, 10, '2018-10-1', ['hi', 1, 2], (33, 44)]
list_b = ['hi', 1, 2]
list_c = list_a.copy() # list_c == [2018, 10, '2018-10-1', ['hi', 1, 2], (33, 44)]
list_d = copy.deepcopy(list_a) # list_d == [2018, 10, '2018-10-1', ['hi', 1, 2], (33, 44)]

# 改变原列表中的可变对象元素
list_a[3].append('new') # list_a == [2018, 10, '2018-10-1', ['hi', 1, 2, 'new'], (33, 44)]

# 浅拷贝中的可变对象会随原列表变化而变化
list_c == [2018, 10, '2018-10-1', ['hi', 1, 2, 'new'], (33, 44)]

# 深拷贝中的可变对象不会随原列表变化而变化
list_d == [2018, 10, '2018-10-1', ['hi', 1, 2], (33, 44)]

# 比较sort() 与 sorted()
list_1 = list_2 = [2,1,4,6,5,3]
list_1.sort() # 原列表变化:list_1 == [1,2,3,4,5,6]
list_3 = sorted(list_2) # 原列表不变:list_2 == [2,1,4,6,5,3]; list_3 == [1,2,3,4,5,6]

Python列表索引为何从0始?

权威解释来自Guido van Rossum(Python之父)的博文:《Why Python uses 0-based indexing》

一句话总结:索引从0开始,切片用法很优雅。

翻译精华如下:

我决定在Python中使用0-based索引方式的一个原因,就是切片语法(slice notation)。

让我们来先看看切片的用法。可能最常见的用法,就是“取前n位元素”或“从第i位索引起,取后n位元素”(前一种用法,实际上是i==起始位的特殊用法)。如果这两种用法实现时可以不在表达式中出现难看的+1或-1,那将会非常的优雅。

使用0-based的索引方式、半开区间切片和缺省匹配区间的话(Python最终采用这样的方式),上面两种情形的切片语法就变得非常漂亮:a[:n]和a[i:i+n],前者是a[0:n]的缩略写法。

如果使用1-based的索引方式,那么,想让a[:n]表达“取前n个元素”的意思,你要么使用闭合区间切片语法,要么在切片语法中使用切片起始位和切片长度作为切片参数。半开区间切片语法如果和1-based的索引方式结合起来,则会变得不优雅。而使用闭合区间切片语法的话,为了从第i位索引开始取后n个元素,你就得把表达式写成a[i:i+n-1]。

……

特别是当两个切片操作位置邻接时,第一个切片操作的终点索引值是第二个切片的起点索引值时,太漂亮了,无法舍弃。例如,你想将一个字符串以i,j两个位置切成三部分,这三部分的表达式将会是a[:i],a[i:j]和a[j:]。

其它编程语言的索引?

索引从0开始的编程语言:C、C++、Python、Java、PHP、Ruby、Javascript...

索引从1开始的编程语言:ABC、Matlab、VB、易语言、大部分shell语言...

索引从其它值开始的编程语言:Pascal、Lua...

还有像表示星期、月份等序列结构的数据,各种编程语言也划分成了不同阵营。

它们出于何种考虑?

C语言:索引从0开始,可以大大提升内存寻址计算的效率,详细分析参考《[C语言数组元素下标为何从0开始](https://blog.csdn.net/bufanq/article/details/51330197)》

大部分shell语言:大多数是从1开始,来源参考[stackexchange这篇问答](https://unix.stackexchange.com/questions/252368/is-there-a-reason-why-the-first-element-of-a-zsh-array-is-indexed-by-1-instead-o)

Pascal、Lua:默认从1开始,但支持改变起始索引值,原因据说是对非专业的开发者更友好,来源参考[这篇知乎问答](https://www.zhihu.com/question/19675689/answer/19174752)

以上列举的原因是最审慎的、体面的解释,话题应该到此终结,因为“索引应该从几开始最好”这个问题的破坏性不亚于“哪种编程语言是最好的”......

优雅漂亮的结尾:生成器表达式

列表生成式是一种漂亮优雅的东西,然而它有一个致命的缺点:它一次性把所有元素加载到内存中,当列表过长的时候,便会占据过多的内存资源,而且,我们通常仅需要使用少数的元素,这样未使用的元素所占据的绝大部分的内存,就成了不必要的支出。

生成器是一种更高级更优雅的东西,它使用“懒加载”的原理,并不生成完整的列表,而是迭代地、即时地、按需地生成元素,这样不仅能极大地节省内存空间,而且,在理论上,它可以生成一个无穷大的列表!

大多数生成器是以函数来实现的,然而,它并不返回(return)一个值,而是生成(yield)一个值,并挂起程序。然后,通过next()方法生成并马上返回一个元素,或者通过for循环,逐一生成和返回全部元素。

next()效率太低,且调用次数越界时会抛出StopIteration的异常,而for循环会自动捕捉这个异常,并停止调用,所以使用更佳。

# 计算斐波那契数列的生成器
def fibon(n):
a = b = 1
for i in range(n):
yield a # 使用yield
a, b = b, a + b

# 计算前1000000个数,通过next()函数,按顺序每次生成一个数
g = fibon(1000000)
next(g) # 1
next(g) # 1
next(g) # 2
next(g) # 3
next(g) # 5
# 以此类推,但若调用超过1000000次,就会报异常StopIteration

# 计算前1000000个数,通过for循环逐一打印生成数
for x in fibon(1000000):
print(x)
生成器表达式与列表生成式极其形似,只是把[]改成了(),但背后的原理大不相同。

l = [x*2 for x in range(5)] # 列表生成式,4以内整数的2倍数
g = (x*2 for x in range(5)) # 生成器表达式
type(l)  # 结果:<type 'list'>
type(g)  # 结果:<type 'generator'>

print(l) # 结果:[0,2,4,6,8]
print(g) # 结果:<generator object at 0x000002173F0EBC50>
next(g)  # 0
next(g)  # 2
next(g)  # 4
next(g)  # 6
next(g)  # 8
next(g)  # Traceback (most recent call last): ....StopIteration

for x in g:
print(x, end=' ') # 结果:0 2 4 6 8

到此这篇关于学习Python列表的基础知识汇总的文章就介绍到这了,更多相关Python列表内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python自定义类并使用的方法
May 07 Python
九步学会Python装饰器
May 09 Python
Android应用开发中Action bar编写的入门教程
Feb 26 Python
TensorFlow如何实现反向传播
Feb 06 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
Apr 17 Python
Flask实现图片的上传、下载及展示示例代码
Aug 03 Python
python读取文件名并改名字的实例
Jan 07 Python
Flask框架模板继承实现方法分析
Jul 31 Python
python3 selenium自动化测试 强大的CSS定位方法
Aug 23 Python
win10环境下配置vscode python开发环境的教程详解
Oct 16 Python
Python使用Tkinter实现转盘抽奖器的步骤详解
Jan 06 Python
Pytorch可视化的几种实现方法
Jun 10 Python
在PyCharm中遇到pip安装 失败问题及解决方案(pip失效时的解决方案)
Mar 10 #Python
python 成功引入包但无法正常调用的解决
Mar 09 #Python
python 中不同包 类 方法 之间的调用详解
Mar 09 #Python
PyCharm 无法 import pandas 程序卡住的解决方式
Mar 09 #Python
python3 使用traceback定位异常实例
Mar 09 #Python
基于Python3.7.1无法导入Numpy的解决方式
Mar 09 #Python
Python 解决火狐浏览器不弹出下载框直接下载的问题
Mar 09 #Python
You might like
如何将一个表单同时提交到两个地方处理
2006/10/09 PHP
PHP开发工具ZendStudio下Xdebug工具使用说明详解
2013/11/11 PHP
php判断是否为json格式的方法
2014/03/04 PHP
php实现无限级分类
2014/12/24 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
PHP反射学习入门示例
2019/06/14 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
javascript 模拟点击广告
2010/01/02 Javascript
将函数的实际参数转换成数组的方法
2010/01/25 Javascript
js 操作select与option(示例讲解)
2013/12/20 Javascript
javascript刷新父页面的各种方法汇总
2014/09/03 Javascript
jQuery中:lt选择器用法实例
2014/12/29 Javascript
解析ajaxFileUpload 异步上传文件简单使用
2016/12/30 Javascript
vue+axios实现登录拦截的实例代码
2017/05/22 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
2019/02/28 Javascript
javascript操作元素的常见方法小结
2019/11/13 Javascript
JS中FormData类实现文件上传
2020/03/27 Javascript
解决vue-loader加载不上的问题
2020/10/21 Javascript
JavaScript枚举选择jquery插件代码实例
2020/11/17 jQuery
[03:48]DOTA2完美大师赛主赛事第二日精彩集锦
2017/11/24 DOTA
python使用pil库实现图片合成实例代码
2018/01/20 Python
使用DataFrame删除行和列的实例讲解
2018/04/08 Python
Centos 升级到python3后pip 无法使用的解决方法
2018/06/12 Python
浅谈pytorch和Numpy的区别以及相互转换方法
2018/07/26 Python
Python实现二叉树的最小深度的两种方法
2019/09/30 Python
Django 项目布局方法(值得推荐)
2020/03/22 Python
python实现每天自动签到领积分的示例代码
2020/08/18 Python
使用CSS3和Checkbox实现JQuery的一些效果
2015/08/03 HTML / CSS
万得城电器土耳其网站:欧洲第一大电子产品零售商
2016/10/07 全球购物
广州喜创信息技术有限公司JAVA软件工程师笔试题
2012/10/17 面试题
化学教学随笔感言
2014/02/19 职场文书
开工典礼策划方案
2014/05/23 职场文书
公司领导九九重阳节发言稿2014
2014/09/25 职场文书
2015年效能监察工作总结
2015/04/23 职场文书
幼儿园小班教师随笔
2015/08/14 职场文书
JavaScript圣杯布局与双飞翼布局实现案例详解
2022/08/05 Javascript