Python|list|切片|列表的运算符、比较及遍历|生成式|元素位置和次数|元素排序和反转|sort() 方法|嵌套的列表|语言基础50课:学习记录(2)-常用数据结构之列表

文章介绍了Python中的列表数据结构,包括定义、运算符、切片操作、比较运算、遍历方法、添加删除元素、元素计数和排序,以及sort()方法和列表生成式。内容覆盖了列表的常用功能和操作技巧,适合初学者掌握列表的使用。
摘要由CSDN通过智能技术生成

目录

系列目录

原项目地址:

8、常用数据结构之列表

列表的运算符

补充:切片及索引介绍:

索引的一般方式

切片操作的基本表达式:object[start:end:step]

 切片操作的 详细切法

列表的比较运算

列表元素的遍历

方法一:

方法二:list本身就具有循环索引的属性

列表的方法

添加和删除元素

元素位置和次数

元素排序和反转

sort() 方法详解

列表的生成式

嵌套的列表


系列目录

[Python|Git remote|hosts|PyCharm常用快捷键|变量转换|命名|类型|运算符|分支|调整tab|循环|语言基础50课:学习记录(1)-项目简介及变量、条件及循环]

[Python|list|切片|列表的运算符、比较及遍历|生成式|元素位置和次数|元素排序和反转|sort() 方法|嵌套的列表|语言基础50课:学习记录(2)-常用数据结构之列表]

[Python|元组|字符串|语言基础50课:学习记录(3)-常用数据结构之元组及字符串相关]

[Python|集合|运算|哈希码|语言基础50课:学习记录(4)-常用数据结构之集合]

[Python|字典|函数和模块|应用及进阶|分数符号(Latex)|String库|operator库|处理数据三步骤|语言基础50课:学习记录(5)-常用数据结构之字典、函数和模块应用及进阶]

[Python|装饰器|执行时间|递归|动态属性|静态方法和类|继承和多态|isinstance类型判断|溢出|“魔法”方法|语言基础50课:学习记录(6)-函数的高级应用、面向对象编程、进阶及应用]

[Python|base64|collections|hashlib|heapq|itertools|random|os.path|uuid|文件|异常|JSON|API|CSV|语言基础50课:学习7]

[Python|xlwt|xlrd|调整单元格样式(背景,字体,对齐、虚线边框、列宽行高、添加公式)|xlutils|openpyxl|只读与只写|图表|语言基础50课:学习(8)]

[Python|python-docx|python-pptx|Pillow|smtplib|螺丝帽短信网关|正则表达式的应用|语言基础50课:学习(9)]

[Python|http|Chrome Developer Tools|Postman|HTTPie|builtwith库|python-whois库|爬虫及解析|语言基础50课:学习(10)]

[Python|线程和进程|阻塞|非阻塞|同步|异步|生成器和协程|资源竞争|进程间通信|aiohttp库|daemon属性值详解|语言基础50课:学习(11)]

[Python|并发编程|爬虫|单线程|多线程|异步I/O|360图片|Selenium及JavaScript|Scrapy框架|BOM 和 DOM 操作简介|语言基础50课:学习(12)]

[Python|MySQL概述|Windows-Linux-macOS安装|MySQL 基本命令|获取帮助|SQL注释|语言基础50课:学习(13)]

[Python|SQL详解之DDL|DML|DQL|DCL|索引|视图、函数和过程|JSON类型|窗口函数|接入MySQL|清屏|正则表达式|executemany|语言基础50课:学习(14)]

原项目地址:

https://hub.fastgit.org/jackfrued/Python-Core-50-Courses.git

8、常用数据结构之列表

有没有办法用一个变量来保存多个数据,有没有办法用统一的代码对多个数据进行操作?答案是肯定的,在Python中我们可以通过容器类型的变量来保存和操作多个数据,我们首先为大家介绍列表(list)这种新的数据类型。

定义和使用列表

```Python

items1 = list(range(1, 10))

print(items1) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

items2 = list('hello')

print(items2) # ['h', 'e', 'l', 'l', 'o']

```

列表的运算符

和字符串类型一样,列表也支持拼接、重复、成员运算、索引和切片以及比较运算,对此我们不再进行赘述,请大家参考下面的代码。

```Python

items1 = [35, 12, 99, 68, 55, 87]

items2 = [45, 8, 29]

# 列表的拼接

items3 = items1 + items2

print(items3) # [35, 12, 99, 68, 55, 87, 45, 8, 29]

# 列表的重复

items4 = ['hello'] * 3

print(items4) # ['hello', 'hello', 'hello']

# 列表的成员运算

print(100 in items3) # False

print('hello' in items4) # True

# 获取列表的长度(元素个数)

size = len(items3)

print(size) # 9

# 列表的索引

print(items3[0], items3[-size]) # 35 35

items3[-1] = 100

print(items3[size - 1], items3[-1]) # 100 100

# 列表的切片

print(items3[:5]) # [35, 12, 99, 68, 55] 从头开始到第5个数据(含第5个)

print(items3[4:]) # [55, 87, 45, 8, 100] 从第4个数以后(不含第4个)

print(items3[-5:-7:-1]) # [55, 68]

print(items3[::-2]) # [100, 45, 55, 99, 35] 从最后(-1)开始,每隔2个数据引用

补充:切片及索引介绍:

参考原文链接:https://blog.csdn.net/Zombie_QP/article/details/125063501

索引的一般方式

一个完整的切片是包含三个参数和两个冒号" : " ,用于分隔三个参数(start_index、end_index、step)。当只有一个“:”时,默认第三个参数step=1;当一个“:”也没有时,start_index=end_index,表示切取start_index指定的那个元素。

切片操作的基本表达式:object[start:end:step]

start:切片的起始位置,如果没有值的话从头开始. end:切片的结束位置,但不包含end(前闭后开),如果没有值的话表示切割到结束为止. step:步长,默认取值为1,如果步长为正数的情况表示从左往右,反正若为负数则表示从右往左. step的正负决定切的方向,这一点需要尤为注意!!!

 切片操作的 详细切法

1.切割单个值

>> a = [1,2,3,4,5,6]

>>> a[0] ##单个数,代表位数,第0位就是a里面的第一位

1

>>> a[5]##a里面的第5位,注意要从0作为第一位开始数

6

2.切割完整对象

>>> b=[6,3,6,7,8,2,5,4]

>>> b[:] ##单独一个冒号,代表从头取到尾,步长默认为1

[6, 3, 6, 7, 8, 2, 5, 4]

>>> b[::]##单独两个冒号一样代表从头取到尾,步长默认为1

[6, 3, 6, 7, 8, 2, 5, 4]

>>> b[::-1]##注意,两个冒号后面是步长,步长为1,故应从右往左取

[4, 5, 2, 8, 7, 6, 3, 6]

即:

>>> b[::]==b[::1]==b[:]

Out[20]: True

3.当start和end全部为正数时.

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> a[1:6] ##默认步长为1,从左往右,注意前闭后开

[1, 2, 3, 4, 5]

>>> a[1:6:-1]

[] ## 当取值的大小方向与步长的方向冲突时,返回值是空.

>>> a[6:1:-1] #不包含结尾,即按提取顺序方向,前闭后开

[6, 5, 4, 3, 2]

>>> a[:6] ## 没有star代表从头开始取,前闭后开

[0, 1, 2, 3, 4, 5]

>>> a[:6:-1] #结尾至6,反向提取,不包含结尾的6,前闭后开

[9, 8, 7]

>>> a[6:] #从6至尾

[6, 7, 8, 9]

>>> a[6::-1] #从6开始包含6,反向截取至开头

[6, 5, 4, 3, 2, 1, 0]

4.当start和end全部取负数的时.

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> a[:-6] ## -6意思是从右往左数的第六位,故第六位是4,然后默认步长为1(从右往左),star未写,故从头开始取到4,前闭后开不取4

[0, 1, 2, 3]

>>> a[-1:-6] #没有第三位,默认为1,正向选取,故为空

[]

>>> a[-1:-6:-1] #前闭后开

[9, 8, 7, 6, 5]

>>> a[-6:-1] ## 这个是从-6取到-1,步长为1,意思是从右往左数第6位到从右往左的第一位,前闭后开

[4, 5, 6, 7, 8]

>>> a[:-6:-1] ## 这个是从0取到-6,步长为-1,开头是冒号,终点为正,则从0开始,终点为为负,则从尾部开始,本例中为-1至-6,前闭后开(不包含-6)

[9, 8, 7, 6, 5]

>>> a[-6:] 这里的开头是4,前闭后开,如果结尾省略,则取至结尾,故全部输出

[4, 5, 6, 7, 8, 9]

>>> a[-6::-1] ## 注意这个不等于[-6:-1],区别是这里是::(两个冒号),两个冒号后连接的是步长,无结尾,则从起始位置,按从右向左全部输出

[4, 3, 2, 1, 0]

5.start和end是正负混合情况时

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> a[1:-6] #前闭后开(不包含-6),步长缺省则为1

[1, 2, 3]

>>> a[1:-6:-1] #步长与首尾方向不一致,输出空白

[]

>>> a[-1:6] #这里默认步长为+1,故不一致,输出空白

[]

>>> a[-1:6:-1] #前闭后开(不包含-6),步长为-1,由右向左输出

[9, 8, 7]

6.连续的切片操作

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> a[:8][2:5][-1:] ## [:8]就是0取到8,在从其中取2到5,最后取-1位

[4]

a[:8] ---- [0,1,2,3,4,5,6,7]

[0,1,2,3,4,5,6,7][2:5]----[2,3,4]

[2,3,4][-1:] ----[4]

7.切片中的三个参数为表达式

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> a[1+2:2*3:7%2] ## 思路一样,运算出来,继续切

[3, 4, 5]

  • 4

8.切片可以操作其他的对象

>>> t = (1,2,3,4,5)

>>> t[1:3]

(2, 3)

>>> s = "ACDRF" ##切片在字母上也是可以使用的,所以说切片很强大

>>> s[1:3]

'CD'

>>> (0, 1, 2, 3, 4, 5)[:3]#元组的切片操作

>>> (0, 1, 2)

>>> for i in range(0,100):

... print(i)

...

>>> for i in range(0,100)[2::3][-10:]: ## 意思是从第二位开始取,步长为3,[-10]则是从倒数10位开始取,意思是去末尾10位.

... print(i)

...

71

74

77

80

83

86

89

92

95

98

列表的比较运算

items5 = [1, 2, 3, 4]

items6 = list(range(1, 5)) #range含头不含尾

# 两个列表比较相等性比的是对应索引位置上的元素是否相等

print(items5 == items6) # True

items7 = [3, 2, 1]

# 两个列表比较大小比的是对应索引位置上的元素的大小

print(items5 <= items7) # True

item[-3] [-2] [-1]

等价于:

item[0 ] [ 1 ] [ 2 ]

item [ len(item) -1]

值得一提的是,由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素。对列表做索引操作一样要注意索引越界的问题,对于有`N`个元素的列表,正向索引的范围是`0`到`N-1`,负向索引的范围是`-1`到`-N`,如果超出这个范围,将引发`IndexError`异常,错误信息为:`list index out of range`。

列表元素的遍历

如果想逐个取出列表中的元素,可以使用`for`循环的,有以下两种做法。

方法一:

```Python

items = ['Python', 'Java', 'Go', 'Kotlin']

for index in range(len(items)):

print(items[index])

```

方法二:list本身就具有循环索引的属性

```Python

items = ['Python', 'Java', 'Go', 'Kotlin']

for item in items:

print(item)

```

讲到这里,我们可以用列表的知识来重构上面“掷色子统计每个点数出现次数”的代码。

```Python

import random

counters = [0] * 6

for _ in range(6000):

face = random.randint(1, 6)

counters[face - 1] += 1

for face in range(1, 7):

print(f'{face}点出现了{counters[face - 1]}次')

```

上面的代码中,我们用`counters`列表中的六个元素分别表示1到6的点数出现的次数,最开始的时候六个元素的值都是`0`。接下来用随机数模拟掷色子,如果摇出1点`counters[0]`的值加`1`,如果摇出2点`counters[1]`的值加`1`,以此类推。大家感受一下,这段代码是不是比之前的代码要简单优雅很多。

列表的方法

和字符串一样,列表类型的方法也很多,下面为大家讲解比较重要的方法。

添加和删除元素

```Python

items = ['Python', 'Java', 'Go', 'Kotlin']

# 使用append方法在列表尾部添加元素

items.append('Swift')

print(items) # ['Python', 'Java', 'Go', 'Kotlin', 'Swift']

# 使用insert方法在列表指定索引位置插入元素

items.insert(2, 'SQL') #2为待出入元素在原list中的索引位置

print(items) # ['Python', 'Java', 'SQL', 'Go', 'Kotlin', 'Swift']

# 删除指定的元素

items.remove('Java')

print(items) # ['Python', 'SQL', 'Go', 'Kotlin', 'Swift']

# 删除指定索引位置的元素

items.pop(0)

items.pop(len(items) - 1)

print(items) # ['SQL', 'Go', 'Kotlin']

# 清空列表中的元素

items.clear()

print(items) # []

```

需要提醒大家,在使用`remove`方法删除元素时,如果要删除的元素并不在列表中,会引发`ValueError`异常,错误消息是:`list.remove(x): x not in list`。在使用`pop`方法删除元素时,如果索引的值超出了范围,会引发`IndexError`异常,错误消息是:`pop index out of range`。

从列表中删除元素其实还有一种方式,就是使用Python中的`del`关键字后面跟要删除的元素,这种做法跟使用`pop`方法指定索引删除元素没有实质性的区别,但后者会返回删除的元素,前者在性能上略优(`del`对应字节码指令是`DELETE_SUBSCR`,而`pop`对应的字节码指令是`CALL_METHOD`和`POP_TOP`,不理解就跳过,不用管它!!!)。

```Python

items = ['Python', 'Java', 'Go', 'Kotlin']

del items[1]

print(items) # ['Python', 'Go', 'Kotlin']

```

元素位置和次数

列表类型的`index`方法可以查找某个元素在列表中的索引位置;因为列表中允许有重复的元素,所以列表类型提供了`count`方法来统计一个元素在列表中出现的次数。请看下面的代码。

```Python

items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']

# 查找元素的索引位置

print(items.index('Python')) # 0

print(items.index('Python', 2)) # 5

# 注意:虽然列表中有'Java',但是从索引为3这个位置开始后面是没有'Java'的

print(items.index('Java', 3)) # ValueError: 'Java' is not in list

```

```Python

items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']

# 查找元素出现的次数

print(items.count('Python')) # 2

print(items.count('Go')) # 1

print(items.count('Swfit')) # 0

```

元素排序和反转

列表的`sort`操作可以实现列表元素的排序,而`reverse`操作可以实现元素的反转,代码如下所示。

```Python

items = ['Python', 'Java', 'Go', 'Kotlin', 'Python']

# 排序

items.sort()

print(items) # ['Go', 'Java', 'Kotlin', 'Python', 'Python']

# 反转

items.reverse()

print(items) # ['Python', 'Python', 'Kotlin', 'Java', 'Go']

```

sort() 方法详解

原文链接:https://blog.csdn.net/horses/article/details/122324556

sort() 方法执行的是原地(in place)排序,意味着它会改变列表中元素的位置。

默认情况下,sort() 方法使用小于运算符对列表元素进行排序。也就是说,更小的元素排在前面,更大的元素排在后面。

如果想要对列表元素进行从大到小排序,可以指定参数 reverse=True。

1、如果列表的元素为字符串,sort() 方法按照字母顺序进行排序。

2、如果列表的元素为数字,sort() 方法按照从小到大的顺序进行排序。

3、元组列表排序

假如存在以下由元组构成的列表:

companies = [('Google', 2019, 134.81),

('Apple', 2019, 260.2),

('Facebook', 2019, 70.7)]

现在我们想要按照收入从高到低对这些公司进行排序。

首先,指定一个排序关键字并传递给 sort() 方法。为了定义排序关键字,我们可以创建一个函数,参数为元组,返回值为排序的元素:

def sort_key(company):

return company[2]

以上 sort_key() 函数接收一个名为 company 的参数并返回它的第三个元素。其中,company 是一个元组(例如 (‘Google’, 2019, 134.81)),company[2] 代表了收入(例如 134.81)。

然后,将 sort_key 函数传递给 sort() 方法:

companies.sort(key=sort_key, reverse=True)

  • 1

sort() 方法会使用函数 sort_key() 返回的结果进行比较。

注意,我们只需要将函数名 sort_key 传递给 sort() 方法,函数名后面没有括号。

完整的代码如下:

companies = [('Google', 2019, 134.81),
             ('Apple', 2019, 260.2),
             ('Facebook', 2019, 70.7)]
# define a sort key
def sort_key(company):
    return company[2]
# sort the companies by revenue
companies.sort(key=sort_key, reverse=True)
# show the sorted companies
print(companies)

输出结果如下:

[('Apple', 2019, 260.2), ('Google', 2019, 134.81), ('Facebook', 2019, 70.7)]

使用 lambda 表达式

为了使代码更加精简, Python 允许定义没有名字的函数:

lambda arguments: expression

没有名字的函数被称为匿名函数,以上语句被称为 lambda 表达式

从技术上来说,lambda 表达式等价于以下函数:

def name(arguments):

return expression

以下示例使用 lambda 表达式按照收入从低到高进行排序:

companies = [('Google', 2019, 134.81),
             ('Apple', 2019, 260.2),
             ('Facebook', 2019, 70.7)]

# sort the companies by revenue
companies.sort(key=lambda company: company[2])

# show the sorted companies
print(companies)

输出结果如下:

[('Facebook', 2019, 70.7), ('Google', 2019, 134.81), ('Apple', 2019, 260.2)]

  • 1

列表的生成式

在Python中,列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。我们给出两段代码,大家可以做一个对比,看看哪一种方式更加简单优雅。

通过`for`循环为空列表添加元素。

```Python

# 创建一个由1到9的数字构成的列表

items1 = []

for x in range(1, 10):

items1.append(x)

print(items1)

# 创建一个由'hello world'中除空格和元音字母外的字符构成的列表

items2 = []

for x in 'hello world':

if x not in ' aeiou':

items2.append(x)

print(items2)

#['h', 'l', 'l', 'w', 'r', 'l', 'd']

# 创建一个由个两个字符串中字符的笛卡尔积构成的列表

items3 = []

for x in 'ABC':

for y in '12':

items3.append(x + y)

print(items3)

```

#['A1', 'A2', 'B1', 'B2', 'C1', 'C2']

通过生成式创建列表。

```Python

# 创建一个由1到9的数字构成的列表

items1 = [x for x in range(1, 10)]

print(items1) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 创建一个由'hello world'中除空格和元音字母外的字符构成的列表

items2 = [x for x in 'hello world' if x not in ' aeiou']

print(items2) # ['h', 'l', 'l', 'w', 'r', 'l', 'd']

# 创建一个由个两个字符串中字符的笛卡尔积构成的列表

items3 = [x + y for x in 'ABC' for y in '12']

print(items3) # ['A1', 'A2', 'B1', 'B2', 'C1', 'C2']

```

下面这种方式不仅代码简单优雅,而且性能也优于上面使用`for`循环和`append`方法向空列表中追加元素的方式。可以简单跟大家交待下为什么生成式拥有更好的性能,那是因为Python解释器的字节码指令中有专门针对生成式的指令(`LIST_APPEND`指令);而`for`循环是通过方法调用(`LOAD_METHOD`和`CALL_METHOD`指令)的方式为列表添加元素,方法调用本身就是一个相对耗时的操作。对这一点不理解也没有关系,记住“**强烈建议用生成式语法来创建列表**”这个结论就可以了。

嵌套的列表

[Python Tutor](<http://www.pythontutor.com/visualize.html>)网站的可视化代码执行功能,看看创建列表时计算机内存中发生了怎样的变化

如果列表中的元素又是列表,那么我们可以称之为嵌套的列表。嵌套的列表可以用来表示表格或数学上的矩阵,例如:我们想保存5个学生3门课程的成绩,可以定义一个保存5个元素的列表保存5个学生的信息,而每个列表元素又是3个元素构成的列表,分别代表3门课程的成绩。

```Python

scores = [[0] * 3 for _ in range(5)]

scores[0][0] = 95

print(scores)

# [[95, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值