一直想学习python,把高淇老师400集的课程下了好几个月了,结果几个月的时间就看了不到30节。这次在西安隔离,待在宿舍好无聊,于是决定,一定要静下心来,把python学完,好吧。那么把这几天的笔记整理一下, 刚好复习一下。
本笔记以高淇老师的课程讲解而来的,大家可以去看看高淇老师的python课程,讲的非常好。那么开始吧。
import turtle
t = turtle.Pen()
for x in range(360):
t.forward(x)
t.left(59)
- 逻辑行首的空白(空格和制表符)用来觉得逻辑行的缩进层次,从而用来决定语句的分组
- 语句从新行的第一列开始
- 缩进风格统一:
- 每个缩进层次使用 单个制表符或四个空格
- python用缩进,不是用{}表示程序块
注释
行注释:每行注释前加#号。当解释器看到#,则忽略这一行#后面的内容 段注释:使用三个连续单引号(''')。当解释看到''',则会扫描到下一个''',然后忽略他们之间的内容。
#1.行注释
'''
2.
段
注
释
'''
行链接符
一行程序长度是没有限制的,但是为了可读性更强,通常将一行比较长的程序分为多行。这时,我们可以使用\行连接符,把它放在行结束的地方。Python 解释器仍然将它们解释为同一行。
a = [10,20,30,40,\
50,60,70,\
80,90,100]
# 输出:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
a = 'abcdefghijklmnopqrstuvwxyz'
b = 'abcdefg\
hijklmn\
opqrst\
uvwxyz'
c = 'abcdefg\
hijklmn\
opqrst\
uvwxyz'
# 输出:
# a:abcdefghijklmnopqrstuvwxyz
# b:abcdefghijklmnopqrstuvwxyz
# c:abcdefg hijklmn opqrst uvwxyz
对象
对象的本质就是:一个内存块,拥有特定的值,支持特定类型的相关操作
- 标识用于唯一标识对象,通常对应于对象在计算机内存中的地址。使用内置函数 id(obj)可返回对象 obj 的标识。
- 类型用于表示对象存储的“数据”的类型。类型可以限制对象的取值范围以及可执行的操作。可以使用 type(obj)获得对象的所属类型。
print(id(3)) #2573173418352
print(type(3)) #<class 'int'>
a=3
print(id(b)) #2573173418352
print(type(b)) #<class 'int'>
b="我爱你"
print(id("我爱你")) #2166580334832
print(id(b)) #2166580334832
print(type("我爱你"))#<class 'str'>
print(type(b)) #<class 'str'>
引用
在 Python 中,变量也成为:对象的引用。因为,变量存储的就是对象的地址。 变量通过地址引用了“对象”。 变量位于:栈内存(压栈出栈等细节,后续再介绍)。 对象位于:堆内存。
标识符
- 区分大小写。如:sxt 和 SXT 是不同的
- 第一个字符必须是字母、下划线。其后的字符是:字母、数字、下划线
- 不能使用关键字。比如:if、or、while 等。
- 以双下划线开头和结尾的名称通常有特殊含义,尽量避免这种写法。比如:__init__是类的构造函数
删除变量和垃圾回收机制
a=123
del a
赋值
链式赋值:链式赋值用于同个对象赋值给多个变量 x=y=123 相当于:x=123; y=123
系列解包赋值:给对应相同个数的变量 a,b,c=4,5,6 相当于:a=4;b=5;c=6
a,b,c=1,2,3
print(a,b,c) #1 2 3
a,b,c=c,b,a
print(a,b,c) #3 2 1
常量
Python 不支持常量,即没有语法规则限制改变一个常量的值。我们只能约定常量的命名规则,以及在程序的逻辑上不对常量的值作出修改。
最基本内置数据类型
- 整型:2345,10,50
- 浮点型:小数,3.14 或者科学计数法 314e-2
- 布尔型:表示真假,仅包含:True、False
- 字符串型:由字符组成的序列。 “abc”,”sxt”,“尚学堂”,”百战程序员”
运算符
加法 3+2 =5
减法 30-5 =25
乘法 3*6 =18
/ 浮点数除法 8/2 =4.0
// 整数除法 7//2 =3
% 模(取余) 7%4 =3
** 幂 2**3 =8
print(7/3) #2.3333333333333335
print(7//3) #2
使用 int()实现类型转换
print(int(123)) #123
print(int(123.453453453)) #123
print(int("435353")) #435353
print(int(True)) #1
print(int(False)) #0
# (错误)print(int("2342sfsdgdg")) #这种无法转换,会报错
时间的表示
计算机时间的表示是从“1970年1月1日 00:00:00 ”开始,以毫秒(1/1000秒)进行计算。我们也把1970年这个时刻成为“unix时间点”
import time
print(time.time()) #从1970年到今天有1635488450.2000031秒
totalSecond=int(time.time())#从1970年到今天有1635488510秒
totalMinute=totalSecond//60 #从1970年到今天有27258143分钟
totalHour=totalMinute//60 #从1970年到今天有454302小时
totalDay=totalHour//24 #从1970年到今天有18929天
totalYear=totalDay//365 #从1970年到今天有51年
布尔值
布尔值:True 和 False 定义成了关键字,但他们的质还是 1 和 0,甚至可以和数字相加
比较运算符
所有比较运算符返回 1 表示真,返回 0 表示假。这分别与特殊的变量 True 和 False 等价
以下假设变量 a 为 15,变量 b 为 30:
- ==(等于) : 比较对象的值是否相等 (a == b) 返回 False
- !=(不等于): 比较两个对象的值是否不相等 (a != b) 返回 true
-
>(大于):返回 x 是否大于 y (a > b) 返回 False
- <(小于):返回 x 是否小于 y (a < b) 返回 true
-
=(大于等于):返回 x 是否大于等于 y。 (a >= b) 返回 False
- <=(小于等于): 返回 x 是否小于等于 y。 (a <= b) 返回True
逻辑运算符
- or逻辑或(x or y):x 为 true,则不计算 y,直接返回 true;x 为 false,则返回 y
- and逻辑与(x and y): x 为 true,则返回 y 的值;x 为 false,则不计算 y,直接返回 false
- not逻辑非(not x):x 为 true,返回 false
print(3==4) #False
print(3<4) #True
print(5!=5) #False
print(3 and True) #True
print(3 and False) #False
print(3>5 or True) #True
print(not 3) #False
同一运算符
- 同一运算符用于比较两个对象的存储单元,实际比较的是对象的地址。
- 运算符描述
- is:is 是判断两个标识符是不是引用同一个对象
- is not:is not 是判断两个标识符是不是引用不同对象
- is 与 == 区别
- is 用于判断两个变量引用对象是否为同一个,即比较对象的地址
- == 用于判断引用变量引用对象的值是否相等,默认调用对象的 eq() 方法
整数缓存问题
Python 仅仅对比较小的整数对象进行缓存(范围为[-5, 256])缓存起来,而并非是所有整数对象。需要注意的是,这仅仅是在命令行中执行,而在 Pycharm 或者保存为文件执行,结果是不一样的,这是因为解释器做了一部分优化(范围是[-5,任意正整数])。
总结
- is 比较两个对象的 id 值是否相等,是否指向同一个内存地址
- == 比较的是两个对象的内容是否相等,值是否相等
- 小整数对象[-5,256]在全局解释器范围内被放入缓存供重复使用
- is 运算符比 == 效率高,在变量和 None 进行比较时,应该使用 is
print(id(3)) #140715204334688
a=3 # 3 有一块地址,a指向存放3的地址,b也是
b=3
print(id(a)) #140715204334688
print(id(b)) #140715204334688
print(a == b) #True 比较两个数值是否相等
print(a is b) #True 比较两个地址是否相等
print(a is 3) #True
print(a is 4) #False
字符串
a='sxt' #sxt
b="sxt" #sxt
c="I'm a teacher" #I'm a teacher
#(错误)d='I'm a teacher' # '与句子中的'配对,所以此时最好用双引号
e='my_name is "YanShen"' # my_name is "YanShen"
#(错误)f="my_name is "YanShen"" # ''与句子中的''配对,所以此时最好用单引号
# 三引号可以写很多行,还有避免句子中 ''和 ' 的配对问题
resume='''name="言深"
company = "浴池" age = 13
lover = "TOM" '''
g=''
print(a,b,'\n',c,'\n',e,'\n',resume,'\n',g)
print(len(g),len(resume)) #0 50
ord() & chr()
- ord()可以把字符转换成对应的 Unicode码
- chr()可以把十进制数字转换成对应的字符
print(ord('A')) #65
print(ord('言')) #39640
print(chr(66)) #'B'
print(ord('深')) #28103
转义字符
(在行尾时) 续行符
\ 反斜杠符号
' 单引号
" 双引号
\b 退格
\n 换行
\t 横向制表符
\r 回车
a = 'I\nlove\nU'
'''
I
love
U
'''
print(a)
print('aaabb\
cccddd')
# aaabbcccddd
字符串拼接
可以使用+将多个字符串拼接起来。
例如:'aa'+ 'bb' ==>'aabb'
- 如果+两边都是字符串,则拼接
- 如果+两边都是数字,则加法运算
- 如果+两边类型不同,则抛出异常
a='aa''bb'
print(a) #aabb
a='aa'
b='bb'
print(a+b) #aabb
可以将多个字面字符串直接放到一起实现拼接。例如:'aa''bb'==>'aabb'
字符串复制
a='abc'
print(a*10) # abcabcabcabcabcabcabcabcabcabc
str()实现数字转型字符串
str()可以帮助我们将其他数据类型转换为字符串
str(5.20) ==> '5.20'
str(3.14e2)==>'314.0'
str(True) ==> 'True'
当我们调用 print()函数时,解释器自动调用了 str()将非字符串的对象转成了字符串
a=123
b=345
print(a+b) #468
a=str(a)
b=str(b)
print(a+b) #123456
使用[]提取字符
字符串的本质就是字符序列,我们可以通过在字符串后面添加[],在[]里面指定偏移量,可以提取该位置的单个字符
- 最左侧第一个字符,偏移量是 0,第二个偏移量是 1,直到 len(str)-1为止
- 最右侧第一个字符,偏移量是-1,倒数第二个偏移量是-2,直到-len(str)为止
a="abcdefg"
a_len=len(a)
print(a[1]) # 第二个字符 b
print(a[1+2]) # b 右两个字符 d
print(a[a_len-1]) # 最后一个字符 g
print(a[a_len-1-2]) # g 左两个字符 e
print(a[-1]) # 最后一个字符 g
print(a[-7]) # 从尾部算起第7个字符,也就是第一个字符 a
replace()实现字符串替换
- 字符串是“不可改变”的,我们通过[]可以获取字符串指定位置的字符,但是我们不能改变字符串。我们尝试改变字符串中某个字符,发现报错了
- 字符串不可改变。但是,我们确实有时候需要替换某些字符。这时,只能通过创建新的字符串来实现
a="abcdefg"
print(a) #abcdefg a指向存放abcdefg的空间
b=a.replace('c','言')
print(b) #ab高defg b指向出发ab高defg的空间
a=b
print(a) #ab高defg a指向b指向的空间
字符串切片操作
a="abcdefghijklmn"
print(a[1:3]) # bc 输出第2个到第3个字符之间
print(a[1:5:2]) # bd 第2个到第6个字符之间每隔1个字符输出一下
print(a[1:500]) # abcdefghijklmn 如果超出字符数量范围,直接按字符串长度去算
print(a[1:500:2]) # 同理
#----------------------------------------------------
print(a[:]) # abcdefghijklmn 输出全部字符
print(a[1:]) # bcdefghijklmn 输出从第二个开始的全部字符
print(a[:7]) # abcdefg 从开头到第7个字符
print(a[::2]) # acegikm 从第1个字符开始,每隔1个输出一个字符
#----------------------------------------------------
print(a[-1:-3]) # 无输出
print(a[-3:-1]) # lm 从倒数第3个输出到倒数第2个
print(a[:-1]) # abcdefghijklm 输出从开头到倒数第2个字符
print(a[-1:]) # n 从倒数第1个开始输出接下来所有字符
print(a[::-1]) # nmlkjihgfedcba 反过来输出
print(a[::-2]) # nljhfdb 从最后一个开始,每隔1个输出1个字符
split()分割字符串
a="to be or not to be"
b=a.split()
# b=['to','be','or','not','to','be']
# 若不指定分隔符,则默认使用空白字符(换行符/空格/制表符)
# 可以基于指定分隔符将字符串分隔成多个子字符串
print(b[1])
b=a.split('be')
# 以 be 作为分隔符
print(b[0],b[1])
# b=['to','or not to']
join()合并字符串
b=['to','be','or','not','to','be']
a='*'.join(b)
print(a) # to*be*or*not*to*be
a=''.join(b)
print(a) # tobeornottobe
字符串驻留机制
字符串驻留:仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串驻留池中。Python 支持字符串驻留机制,对于符合标识符规则的字符串(仅包含下划线(_)、字母和数字)会启用字符串驻留机制驻留机制。但对于pycharm而言,是否符合标识符规则好像都能启动驻留机制
a="abd_33"
b="abd_33"
c="dd#"
d="dd#"
print(a is b) # True
print(c is d) # True
成员操作符
in /not in 关键字,判断某个字符(子字符串)是否存在于字符串中。
a="aabbccdd"
print("aa" in a) # True
print('a' in a) # True
print("aabbccdd" in a) # True
常用查找方法
len()
startswith()
endswith()
find()
rfind()
count()
isalnum()
a="我是言深,言深爱做视频"
print(len(a)) # 字符串长度 96
print(a.startswith('我是言深')) #True 以指定字符串开头
print(a.endswith('做视频')) #True 以指定字符串结尾
print(a.find('言')) #2 第一次出现指定字符串的位置
print(a.rfind('言'))#5 最后一次出现指定字符串的位置
print(a.count("言深")) #2 指定字符串出现了几次
print(a.isalnum()) #False 所有字符全是字母或数字
去除首尾信息
strip()
print(" haha ".strip()) # 默认清除首尾空白符 haha
print("***haha***".strip("*")) # 清楚首尾 * 符号 haha
print("**h*a*h*a**".strip("*")) # 清楚首尾 * 符号,但中间的*不除掉 h*a*h*a
print("*****haha*".lstrip("*")) # 除掉左边的 * 符号,haha*
大小写转换
capitalize()
title()
upper()
lower()
swapcase()
a = "gaoqi love programming, love SXT"
print(a.capitalize()) # 产生新的字符串,单词首字母大写,其余小写 'Gaoqi love programming, love sxt'
print(a.title()) # 产生新的字符串,每个单词都首字母大写 'Gaoqi Love Programming, Love Sxt'
print(a.upper()) #产生新的字符串,所有字符全转成大写 'GAOQI LOVE PROGRAMMING, LOVESXT'
print(a.lower()) #产生新的字符串,所有字符全转成小写 'gaoqi love programming, love sxt'
print(a.swapcase()) #产生新的,所有字母大小写转换 'GAOQI LOVE PROGRAMMING, LOVEsxt'
格式排版
center()
ljust()
rjust()
a="SXT"
print(a.center(10,"*")) # 中间对齐,总共10个字符,其余的地方用 *填充 ***SXT****
print(a.center(10)) # 中间对齐,总共10个字符,其余的地方用空格填充
print(a.ljust(10,"*")) # 左对齐,总共10个字符,其余的地方用* 填充
检查
isalnum()
isalpha()
isdigit()
isupper()
islower()
print("sxt100".isalnum()) #是否为字母或数字 True
print("sxt 尚学堂".isalpha()) #检测字符串是否只由字母组成(含汉字) False
print("234.3".isdigit()) #检测字符串是否只由数字组成 False,因为有小数点
print("23423".isdigit()) # True
print("aB".isupper())#是否为大写字母 False
print("A".isupper())#True
print("\t\n".isspace())#检测是否为空白符 True
print("aa".islower() )#是否为小写字母 True
字符串的格式化
format()
a = "名字是:{0},年龄是:{1}"
# {} 表示占位符,0,1表示第0个,第1个
print(a.format("言深",18)) #输出: '名字是:言深,年龄是:18'
# 用占位符 {} 的话,就要注意元素的顺序
b = "名字是:{0},年龄是{1}。{0}是个好小伙"
print(b.format("言深",18)) # '名字是:言深,年龄是 18。言深是个好小伙'
c = "名字是{name},年龄是{age}"
print(c.format(age=19,name='言深'))# '名字是言深,年龄是 19'
# 这种模式下,元素就无需考虑顺序了
对齐与填充
# ^、<、>分别是居中、左对齐、右对齐,后面带宽度
# :号后面带填充的字符,只能是一个字符,不指定的话默认是用空格填充
print("{:*>8}".format("245"))
# '*****245'
print("我是{0},我喜欢数字{1:*^8}".format("言深","666"))
# '我是言深,我喜欢数字**666***'
数字格式化
a = "我是{0},我的存款有{1:.2f}"
print(a.format("言深",3888.234342))
# '我是言深,我的存款有 3888.23'
print("{:.2f}".format(-3.12)) # 保留小数点后两位 -3.12
print("{:+.2f}".format(-3.124)) # 带符号保留小数点后两位 -3.12
print("{:.0f}".format(3.123)) # 不带小数 3
print("{:.0f}".format(3.983)) # 4
print("{:,}".format(1000000000)) # 以逗号分隔的数字格式 1,000,000,000
print("{:.3%}".format(0.4533425)) # 百分比格式 45.334%
print("{:.2e}".format(10000000000)) # 指数记法 1.00e+10
可变字符串
在 Python 中,字符串属于不可变对象,不支持原地修改,如果需要修改其中的值,只能创建新的字符串对象。但是,经常我们确实需要原地修改字符串,可以使用 io.StringIO对象或 array 模块
import io
s = "hello,sxt"
sio = io.StringIO(s)
print(sio) # <_io.StringIO object at 0x000001FF26533708>
print(sio.getvalue()) # hello, sxt
sio.seek(7) # 找到第8个字符,即x
sio.write("g") # 改为 g
print(sio.getvalue()) # hello, sgt
不换行打印
end = “任意字符串”。实现末尾添加任何内容
print("agdf",end='') #agdf结尾空字符不换行
print("sdaffs",end='\n') #sdaffs结尾换行符
print("fsfsdfs",end="%#%#$%#") #fsfsdfs结尾%#%#$%#不换行
'''
输出:
agdfsdaffs
fsfsdfs%#%#$%#
'''
从控制台读取字符串
我们可以使用 input()从控制台读取键盘输入的内容
myname=input("请输入名字:") # 请输入名字:***言深***
print(myname) # 言深
列表
列表的创建
list()
range()
# 第一种
a = [10,20,'YanShen','sxt']
b = [] #创建一个空列表
# 第二种
# 使用 list()可以将任何可迭代的数据转化成列表。
a = list() # 创建一个空的列表对象
b = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c = list("YanShen,sxt") # ['Y', 'a', 'n', 'S', 'h', 'e', 'n', ',', 's', 'x', 't']
# range()创建整数列表
'''
range() 语法格式为:range([start,] end [,step])
start 参数:可选,表示起始数字。默认是 0
end 参数:必选,表示结尾数字
step 参数:可选,表示步长,默认为 1
python3 中 range()返回的是一个 range 对象,而不是列表。我们需要通过 list()方法将其转换成列表对象。
'''
list(range(3,15,2)) # [3, 5, 7, 9, 11, 13]
list(range(15,3,-1)) # [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4]
list(range(3,-10,-1))# [3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
# 第三种
# 推导式生成列表
a = [x*2 for x in range(5)] #循环创建多个元素 [0, 2, 4, 6, 8]
b = [x*2 for x in range(100) if x%9==0]
# 通过 if 过滤元素 [0, 18, 36, 54, 72, 90, 108, 126, 144, 162, 180, 198]
列表元素的增加与删除
当列表增加和删除元素时,列表会自动进行内存管理,大大减少了程序员的负担。但这个特点涉及列表元素的大量移动,效率较低。除非必要,我们一般只在列表的尾部添加元素或删除元素,这会大大提高列表的操作效率。
append()
# 原地修改列表对象,是真正的列表尾部添加新的元素,速度最快,推荐使用。
a=[10,20,30,40]
a.append(50)
print(a)
+运算符操作
a=[10,20,30,40]
print(id(a)) # 3089976854920
a=a+[50]
print(a) # 10 20 30 40 50
print(id(a)) # 3089550303880
# 通过如上测试,我们发现变量 a 的地址发生了变化。也就是创建了新的列表对象
extend()
# 将目标列表的所有元素添加到本列表的尾部,属于原地操作,不创建新的列表对象。
a=[10,20,30,40]
b=[50,60]
a.extend(b)
print(a) # [10, 20, 30, 40, 50, 60]
insert()
使用 insert()方法可以将指定的元素插入到列表对象的任意制定位置。这样会让插入位置后面所有的元素进行移动,会影响处理速度。涉及大量元素时,尽量避免使用。类似发生这种移动的函数还有:remove()、pop()、del(),它们在删除非尾部元素时也会发生操作位置后面元素的移动。
a=[10,20,30,40]
a.insert(1,9)
print(a) # [10, 9, 20, 30, 40]
乘法扩展
a=[10,20,30,40]
a=a*3
print(a) # [10, 20, 30, 40, 10, 20, 30, 40, 10, 20, 30, 40]
列表元素的删除
del()
# 删除列表指定位置的元素。
a=[10,20,30,40,50]
del a[1]
print(a) # [10, 30, 40, 50]
pop()
# pop()删除并返回指定位置元素,如果未指定位置则默认操作列表最后一个元素
a=[10,20,30,40,50]
print(a.pop()) # 50
print(a) # [10, 20, 30, 40]
print(a.pop(1)) # 20
print(a) # [10, 30, 40]
remove()
# 删除首次出现的指定元素,若不存在该元素抛出异常。
a = [10,20,30,40,50,20,30,20,30]
a.remove(20)
print(a) # [10, 30, 40, 50, 20, 30, 20, 30]
列表元素访问和计数
通过索引直接访问元素
a=[10,20,30,40,50]
print(a[2]) # 30
index()
# 获得指定元素在列表中首次出现的索引
# index()可以获取指定元素首次出现的索引位置。语法是:index(value,[start,[end]])。
# 其中,start 和 end 指定了搜索的范围。
a=[10,20,30,40,50,10,20,10]
b = a.index(10) # 0
c = a.index(10,1) # 5 第2个元素之后10的位置
d = a.index(10,3,7) # 5 第4个元素到第8个元素之间,10的位置
count()
a=[10,20,30,40,50,10,20,10]
# count()可以返回指定元素在列表中出现的次数
print(a.count(10)) # 3
len()返回列表长度
a=[10,20,30,40,50,10,20,10] # len()返回列表长度,即列表中包含元素的个数。
print(len(a)) # 8
成员资格判断
a=[10,20,30,40,50,10,20,10]
print(20 in a) # True
print(100 not in a) # True
print(30 not in a) # False
切片操作
'''
切片 slice 操作可以让我们快速提取子列表或修改。标准格式为:
[起始偏移量 start:终止偏移量 end[:步长 step]]
注:当步长省略时顺便可以省略第二个冒号
# [:]:提取整个列表
# [start:]:从 start 索引开始到结尾
# [:end]:从头开始知道 end-1
# [start:end]:从 start 到 end-1
# [start:end:step]:从 start 提取到 end-1,步长是 step
# 其他操作(三个量为负数)的情况:
# [10,20,30,40,50,60,70][-3:] 倒数三个 [50,60,70]
# -7 -6 -5 -4 -3 -2 -1
# [10,20,30,40,50,60,70][-5:-3] 倒数第五个到倒数第三个(包头不包尾) [30,40]
# [10,20,30,40,50,60,70][::-1] 步长为负,从右到左
# 反向提取 [70, 60, 50, 40, 30, 20, 10]
'''
列表的遍历
a=[10,20,30,40,50,10,20,10]
for x in a:
print(x,end=' ') # 10 20 30 40 50 10 20 10
列表排序
# 第一种
a = [20,10,30,40]
a.sort() #默认是升序排列
print(a) # [10, 20, 30, 40]
a = [10,20,30,40]
a.sort(reverse=True) #降序排列
print(a) # [40, 30, 20, 10]
import random
random.shuffle(a) #打乱顺序
print(a) # [40, 30, 20, 10]
random.shuffle(a) #打乱顺序
print(a) # [10, 20, 40, 30] 每次打乱都可能不一样
# 第二种 建新列表的排序
# 我们也可以通过内置函数 sorted()进行排序,这个方法返回新列表,不对原列表做修改。
a = [20,10,30,40]
id(a) # 46016008
a = sorted(a) #默认升序
id(a) # 45907848
a = [20,10,30,40]
id(a) # 45840584
b = sorted(a)
id(a) # 45840584
id(b) # 46016072
print(a) # [20, 10, 30, 40]
print(b) # [10, 20, 30, 40]
c = sorted(a,reverse=True) #降序
# 通过上面操作,我们可以看出,生成的列表对象 b 和 c 都是完全新的列表对象。
reversed()返回迭代器
# reversed()不对原列表做任何修改,只是返回一个逆序排列的迭代器对象。
a = [20,10,30,40]
c = reversed(a)
print(c) # 不是列表类型
# <list_reverseiterator object at 0x000002382F9760F0>
print(list(c)) # [40, 30, 10, 20]