网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
* [第二个:升级版使用——使用列表生成式的同时使用函数处理](#_521)
* [第三个:高级版使用——删选列表中特定元素的高级操作](#_534)
- [二、列表生成器](#_557)
- [三、函数列表生成器](#_579)
+ [(5)删除列表中的重复元素并保持顺序不变](#5_685)
+ - [第一个版本:](#_686)
- [第二个版本:](#_715)
每篇前言:
- | |
| — |
| 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 |- 🔥🔥本文已收录于Python全栈系列专栏:《Python全栈基础教程》
- 🔥🔥热门专栏推荐:《Django框架从入门到实战》、《爬虫从入门到精通系列教程》、《爬虫高级》、《前端系列教程》、《tornado一条龙+一个完整版项目》。
- 📝📝本专栏面向广大程序猿,为的是大家都做到Python从入门到精通,同时穿插有很多很多习题,巩固学习。
- 🎉🎉订阅专栏后****可私聊进一千多人Python全栈交流群(手把手教学,问题解答); 进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
- 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!
Python数据类型(三)
1 list列表
List(列表) 是 Python 中使用最频繁的数据类型。
列表可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串甚至可以包含列表(所谓嵌套)。
列表用[ ]标识。是python最通用的复合数据类型。
列表中的值得分割也可以用到变量[头下标:尾下标],就可以截取相应的列表,从左到右索引从0开始的(跟字符串一样)。
加号(+)是列表连接运算符,星号(*)是重复操作。
基本概念:在Python程序中使用中括号"[]"来表示列表,并用逗号分隔其中的元素。
books = ['python从入门到放弃', 'C从入门到放弃', '汇编从入门到放弃'] # 创建一个名为books的列表
print(books) # 输出列表books中的信息
代码讲解:在上述代码中,创建一个名为“books”的列表,在列表中存储了三个元素,执行后会将列表打印输出。
1.1 第一小节课 之 列表中的索引及切片(分片)
注意:索引及切片(分片)对于任何数据类型都有效哦!
①如何取列表中的元素(聪明的同学都已经答出来是通过索引取值了!)
在python程序中,因为列表是一个有序集合,所以要想访问列表中的任何元素,只需要将该元素的位置或索引告诉Python即可(但是要注意的是:列表中元素的索引是从0开始!)。要想访问列表元素,可以指出列表的名称,再指出列表的索引,并将其放在方括号内。
骚操作来袭:如果在一个项目中,我们不知道存储项目数据的这个列表到底多长,而我们就是要它最后一个元素该怎么做呢?
其实方法很多很多哦!但是老师在这里讲一个通过下标取它的骚操作:
a = [1,2,3,4,5,6,7,8,9,10]
print(a[-1]) # 输出为 10。 从列表右侧向左侧第一个是-1,以此类推。
②首先将列表切片的万能公式交给大家
- (一听万能公式是不是感觉可牛逼,但是同学们不要形成惯性思维,一看到万能公式就想着背住就完事了哦!要通过老师下面的讲解彻底理解它哦!)
切片
(万能公式一大注意点:左闭右开!)
第一个:
正方向[起始位置:结束位置+1:步长]
第二个:
注(如果步长为负数,则逆序)
反方向[开始位置:结束位置-1:负数]
是不是看了万能公式后一头懵,那就对了,都给我打起精神,咱们一起来好好研究这个万能公式究竟是个啥意思!
(1)第一个万能公式讲解——正方向[起始位置:结束位置+1:步长]
知识补给站(一个简便的创建数字列表的方法——使用方法range(),注意这个方法也是左闭右开哦!):
上代码:
numbers = list(range(0,11))
print(numbers) # 输出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- 第一个代码片段讲解:
正方向的意思是从列表左到右取值!
起始位置是想要获取的列表元素的起始索引;
结束位置是想要获取的列表元素的结束索引加一。
步长是每一次取值跳几个索引,默认值是1。
numbers = list(range(0,11))
print(numbers[0:5]) # 等价于:print(numbers[0:5:1])
- 第二个代码片段讲解:
给定列表a = [1,2,3,4,5,6,7,8,9,10],我们需求是取出列表中所有奇数——这就用到了正向切片!
a = [1,2,3,4,5,6,7,8,9,10]
print(a[0:(9+1):2]) # print(a[0(起始位置):9+1(结束位置+1):2(隔两个取一次)])
需求完美完成!
课上小问题(会的举手快快快——加平时成绩哦!)
如何取该列表中的所有偶数呢?
答案:
print(a[1(起始位置):9+1(结束位置+1):2(隔两个取一次)])
运行结果为 [2,4,6,8,10]
(2)第二个万能公式讲解——反方向[开始位置:结束位置-1:负数]
注:如果步长为负数,则逆序!
- 第一个代码片段讲解:
反方向的意思是从列表右到左取值!
起始位置是想要获取的列表元素的结束索引(包括这个元素哦!);
结束位置是想要获取的列表元素的起始索引减一。
【上面是按照正向索引讲的,不是很好理解。其实反方向这个公式,我们完全可以理解为是从列表右侧向左侧取值。第一个值就是从右侧的起始位置,第二个值就是从右侧开始的结束位置,就要加一,而对于列表索引来说就是减一。这也说明了遵循左闭右开!】
步长是每一次取值跳几个索引,如果是逆序切片就必须给负数的步长!。
a = [1,2,3,4,5,6,7,8,9,10]
print(a[9:1:-1])
- 第二个代码片段讲解:
给定列表a = [1,2,3,4,5,6,7,8,9,10],我们需求是倒序取出列表中所有偶数——这就用到了逆序切片!
a = [1,2,3,4,5,6,7,8,9,10]
print(a[::-2]) # 简写了,起始位置和结束位置两个地方没写,则为整个列表
需求完美实现:
总结升华:
L[m:n]表示:从索引m开始直到索引n(不包含n)取数据;
L[m:n:p]表示:从索引m开始直到索引n(不包含n)取数据,每p个取一个。
- m、n、p、可以为负数:
①p>0 从首部往尾部方向取,p<0是从尾部向首部取。
②m、n大于0表示索引值。
③m、n小于0表示倒数第几个。
L[-5:-2] 表示倒数第5到倒数第2元素(不包含倒数第2个元素)从首到尾的顺序取。
L[-2:-5:-2] 表示倒数第2到倒数第5元素(不包含倒数第5个元素)从尾到首的顺序取,每2个取一个。
一般流程:m、n如果为负数先转为正数然后根据p的方向取值(初学可能不是很理解这句话,可以用多了再来揣度)。 - m、n、p可以缺省:L[::]
m缺省为p表示的方向的首元素,n缺省为p表示的方向的尾元素的后一个,p缺省表示1
L = [‘Google’, ‘Baidu’, ‘Taobao’, ‘edu360’, ‘xiaoniu’]
1.2 第二小节课 之 列表中的骚方法操作
①list.append(obj)
- 在列表末尾添加新的对象 列表专属
a = [1,2,3]
a.append('s')
print(a) # 输出为:[1, 2, 3, 's']
②list.insert(x,y)
- 自定义位置添加元素,将元素插入到指定的索引 加入单个值!!!(参数含义:第一个是所添加的下标指定位置,第二个是需要添加的元素)
a = [1,2,3]
a.insert(1,'new\_num') #
print(a) # 输出为:[1, 'new\_num', 2, 3]
③list.extend(sep)
- 在列表末尾一次性追加另一个序列(字符串,列表,元组)中的多个值(用新列表扩展原来的列表)
a = [1,2,3]
a.extend('abc')
print(a) # 输出为:[1, 2, 3, 'a', 'b', 'c']
④list.pop()
- 没有传参数的情况下会删除列表的最后一个元素,如果带了参数的话就删除指定索引位置的元素
# 未加参数——删除最后一个元素!
a = [1,2,3]
a.pop()
print(a) # 输出为[1,2]
加参数——删除指定索引位置的元素!
b = [1,2,3]
a.pop[1]
print(a) # 输出为[1,3]
⑤list.remove()
- 删除指定元素,但是在有多个相同项的情况下只删除第一个
a = [1,2,3,4,1,1,1]
a.remove(1)
print(a) # 输出为[2,3,4,1,1,1]
⑥list.clear()
- 清空列表,删除列表里所有的值,括号内不需要带参数
a = [1,2,3,4,1,1,1]
a.clear()
print(a) # 输出为[]
⑦list.count(obj)
- 统计某个元素在列表中出现的次数,计数(可以赋值可以print)
a = [1,2,3,4,1,1,1]
num = a.count(1)
print(num) # 输出为 4
⑧list.index(x,y)
- 第一个参数是要查找的值,第二个参数是查找开始的下标位置。每次查找只会显示查找到的第一个值的下标。不加第二个参数的话默认从下标0开始,没有查找到的时候会报错 (可以赋值可以print)
a = [1,2,3,4,1,1,1]
index1 = a.index(1)
index2 = a.index(1,2)
print(index1) # 输出为 0
print(index2) # 输出为 4
⑨join()
- 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。使用方法:str.join(sequence),sequence为要连接的元素序列。返回通过指定字符连接序列中元素后生成的新字符串。
a = ['a', 'b', 'c']
end = "-".join(a)
print(end) # 输出为a-b-c
⑩list.reverse()
- 反向列表中元素
⑩①list.sort([func])
- 对原列表进行排序
⑩②列表操作中还有深浅复制的方法
拓展:列表排序的方法!
①sort() --->对列表里的数值从小到大排序,只能是数字,如果列表里有字符串的话那么需要在括号内加入:key=str 如a.sort(key=str) 。字符串的排序根据于ASCII的字母排序。
上代码:
a = ['a', 'd', 'f', 'b']
a.sort(key=str)
print(a) # 输出为:['a', 'b', 'd', 'f']
拓展:使用sort()方法对列表里的数值从大到小排序;如果列表里有字符串的话加入参数key=str,如a.sort(key=str,reverse=True)。
上代码:(列表含有字符串)
a = ['a', 'g', 'b', 'c']
a.sort(key=str,reverse=True)
print(a) # 输出为:['g', 'c', 'b', 'a']
上代码:(列表元素都是数字)
a = [1,9,3,7]
a.sort(reverse=True)
print(a) # 输出为:[9,7,3,1]
②reverse() --->对列表里的数值从大到小反序,只能是数字。
上代码:
a = [1, 4, 3, 8]
a.reverse()
print(a) # 输出为: [8,3,4,1]
一些在项目中常用的列表小操作!
(1)找出列表中出现次数最多的元素
如果有一天,同学们在工作,Boss突然抛出来一个需求:**在python程序中如何找到列表中出现次数最多的元素!**难道你要使用循环啥的一步步瞎搞?效率低B格也不高。这里为师教你们一种简单易上手B格高的方法——使用collections模块中的Counter类,调用Counter类中的most_common()函数来实现!
直接上代码:
from collections import Counter
words = [
'look', 'into', 'my', 'AAA', 'look', 'into', 'my', 'AAA',
'the', 'AAA', 'the', 'eyes', 'not', 'BBB', 'the', 'AAA',
"don't", 'BBB', 'around', 'the', 'AAA', 'look', 'into',
'BBB', 'AAA', 'BBB', 'under'
]
word_counts = Counter(words)
print('统计所有元素出现次数:',word_counts)
top_three = word_counts.most_common(3)
print('统计出现次数最多的三个元素:',top_three)
输出为:
统计所有元素出现次数: Counter({'AAA': 6, 'the': 4, 'BBB': 4, 'look': 3, 'into': 3, 'my': 2, 'eyes': 1, 'not': 1, "don't": 1, 'around': 1, 'under': 1})
统计出现次数最多的三个元素: [('AAA', 6), ('the', 4), ('BBB', 4)]
(2)排序类定义的实例
项目背景:如果我们在一个项目中,一个类定义的实例有很多个,而我们的需求是将这些实例排序该怎么做呢?
使用内置函数sorted()可以接收一个用来传递可调用(callable)对象的参数key,而这个可调用对象会返回待排序对象中的某些值,sorted()函数则利用这些值来比较对象。
假如在程序中存在多个User对象的实例,如果想通过属性user_id来对这些实例进行排序,可以提供一个可调用对象,它将User实例作为输入,然后返回user_id。下面代码演示排序上述User对象实例的过程:
class User:
def \_\_init\_\_(self, user_id):
self.user_id = user_id
def \_\_repr\_\_(self):
return 'User({})'.format(self.user_id)
# 原来的排序
users = [User(91), User(17), User(18)]
print(users)
# 根据user\_id排序——两种方法
# ①使用lambda表达式:
print(sorted(users, key=lambda u: u.user_id))
# ②使用内置函数operator.attrgetter()进行处理:
from operator import attrgetter
print(sorted(users, key=attrgetter('user\_id')))
(3)命名切片(高阶用法)
项目问题背景:
在python程序中,有时会发现编写的代码由于过度的使用硬编码的切片索引(就像上面第二小节课讲的那样!),而使得我们的项目代码变得杂乱无章而无法阅读,此时就需要清理它们。同时过度的使用硬编码的索引值,也会降低代码的可读性和可维护性。
解决方法:
在python程序中,使用函数slice()可以实现切片对象,能够在切片操作函数中实现参数传递功能,可以被用在任何允许进行切片操作的地方。
使用函数slice()的语法格式:
class slice(stop)
class slice(start, stop, step)
start:起始位置;
stop:结束位置;
step:间距。
上代码讲解:
items = [0, 1, 2, 3, 4, 5, 6]
a = slice(2,4) # 定义一个slice对象实例a
print(items[2:4]) # 使用常用的切片取列表值
print(items[a]) # 使用slice对象实例a取列表值
items[a] = [10, 11]
print(items)
print(a.start) # 分别通过属性a.start,a.stop,a.step获取该slice对象的信息
print(a.stop)
print(a.step)
s = 'verygoodman'
# 使用indices(size)函数将切片映射到特定大小的序列上,这将会返回一个(start,stop,step)元组,
# 所有的值都已经正好限制在边界以内,这样当进行索引操作时可以避免出现IndexError异常。
print(a.indices(len(s)))
print(\*a.indices(len(s))) # 分解元组
for i in range(\*a.indices(len(s))):
print(s[i])
深入讲解——使用indices(size)函数的好处,以及上述注释中写的为何使用此函数当进行索引操作时可以避免出现IndexError异常!
直接上代码讲解:
a = slice(2,4) # 定义一个slice对象实例a
s = 'ver' # 此时序列s
# 使用indices(size)函数将切片映射到特定大小的序列上,这将会返回一个(start,stop,step)元组,
# 所有的值都已经正好限制在边界以内,这样当进行索引操作时可以避免出现IndexError异常。
print(a.indices(len(s)))
print(\*a.indices(len(s))) # 分解元组
for i in range(\*a.indices(len(s))):
print(s[i])
一节课让你彻底搞懂python中的单星号(*)和双星号(**)的区别及项目实际用法——给我学!
观察运行结果会发现:我们虽然定义的slice对象实例的切片范围是2-4,但是由于映射到的序列整体范围只有0-3(左闭右开),因为我们使用了indices(size)函数,它会将切片范围限制在这个映射的序列范围边界以内:2-3,这样虽然我们定义的slice对象实例范围超出了此序列s的范围,但是因为indices(size)函数的使用并不会报错,而是类似于动态的自适应变化!
(4)生成list相关函数(重点!!!!)
一、列表生成式
列表推导式(List Comprehension)是一种简化代码的优美方法。官方文档——列表推导式提供了一种创建列表的简洁方法。 使用列表推导式能够非常简洁的构造一个新列表,只需要用一个简洁的表达式即可对得到的元素进行转换变形。
# 使用Python列表推导式的语法格式:
variable = [out\_exp\_res for out\_exp in input\_list if out\_exp == 2]
out_exp_res:列表生成元素表达式,可以是有返回值的函数;
for out_exp in input_list:迭代input_list,将out_exp传入out_exp_res表达式中;
if out_exp == 2:判断根据条件可以过滤哪些值。
先来讲讲—range函数list序列迭代对象
- Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。
- Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。
①range 语法:
range(stop)
range(start, stop[, step])
②参数说明:
start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
end: 计数到 end 结束,但不包括 end。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
# -\*- coding: utf-8 -\*-
"""
\_\_author\_\_ = 小小明-代码实体
"""
# coding=utf-8
print(list(range(10))) # 产生一个0-9的序列
print(list(range(3, 10))) # 产生一个3-9的序列
print(list(range(0, 10, 3))) # 产生从0开始,按3递增,最大值为9的序列
print(list(range(10, -1, -1))) # 产生从10开始,最小值为0的递减序列
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
# -\*- coding: utf-8 -\*-
"""
\_\_author\_\_ = 小小明-代码实体
"""
# coding=utf-8
print(list(range(10))) # 产生一个0-9的序列
print(list(range(3, 10))) # 产生一个3-9的序列
print(list(range(0, 10, 3))) # 产生从0开始,按3递增,最大值为9的序列
print(list(range(10, -1, -1))) # 产生从10开始,最小值为0的递减序列
[外链图片转存中…(img-q8P6Tm8v-1715744126442)]
[外链图片转存中…(img-M9QzxLpP-1715744126443)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!