Python学习笔记-总

本文最后更新于:2024年8月11日 晚上

综述

本文用于记录平日学习Py中发现的奇奇怪怪的玩法和不知道的知识,以备查阅

Date:2022-04

使用函数组合对输入内容进行处理

1.核心是 map(Function,Data)函数,将F函数一 一映射到数据集Data中,本例中使用的函数是隐函数,处理数据为input并切片后的内容

2.lambda函数:第一个x为形参,:后为对x做类型转换处理

3.list,将结果转换成列表,否则似乎会返回容器代码

1
result = list(map(lambda x:float(x),input().split(',')))

字符串切片、筛选、转列表快速方法

1.核心是列表解析,原方法为 x for x in list [if],此处进行改进,for前 x 为最终形成进入列表的参数,进行int()处理,for x in Str表示x在列表内,if 是对x的判断,对x进行一步筛选

1
2
Str = '1,2,3,4,a,b,c'
L = [int(x) for x in Str.split(',') if x.isdigit()]

使用隐函数对列表中字典按规定排序

有多个在一个列表中的字典,且存在可排序选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
data = [
{
"name": 'Dustella',
"xp": 100
},
{
"name": "伊蕾娜",
"xp": 200,
},
{
"name": "Other",
"xp": 0,
},
]

希望对列表中的元素按照XP值的大小进行排序,代码如下:

1
2
result = sorted(data,key=lambda x: x['xp'])
print(result)

解析:

1.sorted(Data,Key=,[reverse=False] )方法可对可迭代对象进行排序,Data为排序对象,key为排序规则,如果使用 abs 没有括号!则对每个元素的绝对值大小进行排序,reverse为是否逆序,默认为升序排列

2.使用隐函数,对每个元素(本例中是字典)中的 ‘xp’ 项的值进行排序,相当于如下代码:

1
2
3
4
5
def arrange():
return x['xp']

result_2 = sorted(data,key = arrange)
print(result_2)

数学方法类:

1
2
3
4
5
6
7
8
9
10
11
import math
A = 5
B = 25
# 求取一个数A的阶乘
math.factorial(A)

# 求一个数A的n次方
math.pow(A,n)

# 对A,B两数同时求余和整除,返回元组
divmod(A,B) == (A//B,A%B)

判断回文:

1
2
3
4
5
6
7
Str = 'abccba'
# 切出字符串前半段和后半段,对后半段逆序,直接判断是否相等
# 如果不是偶数序列,需要剔除中间项,本题直接使用列表访问的逆序方法,最终实现如下
if len(m)%2 == 0 and m[: int(len(m) / 2)] == m[:int(len(m) / 2)-1 : -1]:
print('True')
elif len(m)%2 != 0 and m[:int(len(m) / 2)] == m[:int(m) / 2 : -1]
print('False')

二维列表

创建二维列表<列表推导创建法>

1.引入random,设置一个种子(这步不是必要的,为了确保结果能够复现)

  • random.randint 每一行的元素都是0~9之间的随机整数
  • 第一个range(1,6)表示有 5 列,或每行有 5 个元素
  • 第二个range(1,5)表示有 4 行,或每列有 4 个元素
1
2
3
4
import random
random.seed(2233)
matrix = [ [random.randint(0,9) for x in range(1,6)] for x in range(1,5) ]
print(matrix)

以矩阵形式输出二维列表

1
2
for i in range(0,len(source)):
print(source[i])

求取二维列表的最大值

1
2
3
4
mid = []
for i in range(0,len(source)):
mid.append(max(source[i]))
print(max(mid))

求取一个二维方阵的主对角线或副对角线的和

1
2
3
4
5
6
7
8
9
10
11
# 主对角线
mid_2 = []
for i in range(0,len(source)):
mid_2.append(source[i][i])
print(sum(mid_2))

# 副对角线
mid_3 = []
for i in range(0,len(source)):
mid_3.append(source[i][len(source)-i-1])
print(sum(mid_3))

简便方法求取两数之间的奇数和及偶数和

1
2
3
4
5
6
n = 1
m = 9
# 求取偶数和
print(sum([x for x in range(n+1 , m) if x % 2 == 0 ]))
# 求取奇数和
print(sum[y for y in range(n+1 , m) if y % 2 != 0])

关于字典

小任务:词频统计等

给出一段文字,要求分别求出单词、标点的个数,然后将单词逆序,最后利用字典统计各个词频:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 输入,并进行预处理
str = 'This is my father , This is my mother , This is me'
str_split = str.split()

# 统计单词、标点词频
re_1 = [x for x in str_split if x.isalpha()]
re_2 = set([x for x in str_split] - set(re_1))

print('单词个数为 {},标点个数为 {}'.format(re_1,re_2))

# 将每个单词逆序,最后拼接
re_3 = ''
for i in str_split:
mid = ' '.join(list(i)[::-1])
re_3 += ' ' + mid
print(re_3)

# 使用字典统计词频
re_4 = dict()
for word in str_split:
re_4[word] = re_4.get(word,0) + 1
print(re_4)

上述代码不是很复杂,重点讲解字典部分:

​ 对于每一个在待处理列表里的元素

​ 对于word键,定义值为 【查询该word键的值的结果,没有该键则赋值为0】 加上 【1】

聪明在于,对dict[Key]赋值,不存在的键值将被自动创建,不需要再进行逻辑判断

更聪明在于,使用dict.get(Key,Default Value)的方式尝试去访问这个键的值,如果存在,就直接调用先前统计的量,再加一,如果不存在,这个函数会自动创建键值并赋值为Default Value,可以避免直接访问不存在的键导致报错的情况。也避免了再用逻辑判断其值是否存在,不存在就创建,存在就加一的复杂情况。

其他一些好玩的用法

只遍历Key或Value

1
2
3
4
5
6
7
8
xp = {'Dustella':100,'Orange':50,'LY':20,'猫猫':100}
# 对key遍历
for key in xp.keys():
print(key)

# 对Value遍历
for value in xp.values():
print(value)

遍历键值对 < ! >

1
2
3
4
5
6
7
8
9
10
11
12
xp = {'Dustella':100,'Orange':50,'LY':20,'猫猫':100}
# 以元组方式返回键值对【常规遍历】
for tup in xp.items():
print(tup)

# 直接返回键值,不用元组【双重遍历】
for key,value in xp.items():
print(key,item)

# 直接返回键值,但是交换键值【双重遍历】
for key,value in xp.items():
print(value,key)

基于元组列表的字典解析 < ! >[字典推导]

如果有一个元组组成的列表,可以像类似列表解析一样,解析成一个字典:

1
2
3
4
5
6
xp = [('Dustella',100),('Orange',50),('猫猫',100)]
# 用双重遍历的方式将列表中元组解析成字典
xp_dic = {name:value for name,value in xp}

# 用双重遍历的方式,将键值对倒置,形成字典
xp_dic_2 = {value:name for name,value in xp}

双列表转字典的Zip方法

可以用Zip方法把两个列表缝合成元组,键值一 一对应:

1
2
3
4
xp_name = ['Dustella','Orange']
xp_value = [100,50]
# 将两个列表缝合成字典
xp_dic = dic(zip(xp_name,xp_value))

如果列表里有多个双元组,可以直接套入dic()函数,但对三元组必须使用zip(),注意是双元组内直接形成键值

1
2
xp = [('Dustella',100),('Orange',50)]
xp_dic = dic(xp)

作用域访问和可变参数传递问题

作用域访问

变量所在作用域类型

【1】B:内置作用域:储存一些Python自带的函数和方法

【2】G:全局作用域:在函数体外声明的方法、变量,因为Py没有main函数,因此没有放在def function里的变量都是全局变量

【3】L:局部作用域:在函数体内声明的变量,各个函数体内的变量相互隔离,互不干扰

【4】E:嵌套作用域:预先在函数体外声明,在函数体内调用、修改的nonlocal变量,可以实现在某函数体内修改局域外的变量

作用域访问顺序

调用优先级:LEGB == 本域 -> 在本域的嵌套域 -> 父域 -> 内置作用域

global 强制声明一个全局变量,除了某些情况要用到,一般比较少用

local 声明一个在本域的局部变量

nonlocal 声明一个在本域的嵌套变量,这个变量必须在父域得到声明

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def main():
def A():
scamp = 'Local Var' #在子函数A声明在A子域下的变量
def B():
scamp = 'Can Change?' #尝试修改scamp

# A、B两个函数下的scamp内容相互隔离
scamp = 'Big local var'
# 定义一个在main函数子域的变量,对于A、B来说是父作用域

def C():
print(scamp)
# 子域发现没有这个变量时会尝试向父域请求这个变量

def D():
unlocal scamp = 'Magic Change'

# 在D的子域声明一个嵌套变量,这个变量在父域main已经声明过,直接对其进行更改

A()
print(scamp)
# 直接调用A函数,A下定义了一个scamp,但是在全局的print不能访问子域
# 变量的访问只能向上,因此print去内置作用域寻找是否定义了一个变量scamp,显然是不存在的
# 因此抛出Not defined
scamp = 'Global Var'
print(scamp)

# 在main函数外,也就是全局,声明一个全局变量,与main下的scamp隔离

如果学过C++或指针概念会更好理解

函数参数可变对象的传递

导入

一切都源于HZH的题目

黄HZ需要实现,输入一个字符串,将字符串末尾提至首部,生成列表打印

1
2
3
4
5
6
7
8
9
10
11
12
13
def shift(lst):
lst=list(lst)
m=lst[-1] # 访问传入的列表的尾部元素,储存
lst.pop() # 删除原列表的尾部元素
lst.insert(0,m) # 在列表0号位置插入元素

# 默认return为None

# 以下代码不可修改,只能定义函数

list1 = input().split(",")
shift(list1)
print(list1)

结果显然是办不到的,列表生成了,但是没法把尾部元素放置到头部

起初,我认为是没有return的问题,只需要把修改好的列表lst写入return,并赋值给一个变量,然后赋值给一个变量,并打印即可。由于无法修打印代码,于是这个思路虽然实现了,但是还是改了,最终使用全局变量解决,实现的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
def shift(lst):
lst_1 = list(lst)
m = lst_1[-1]
lst_1.pop()
lst_1.insert(0, m)
global list1 # 添加一个全局变量,用这个变量接取值即可不用return
list1 = lst_1

# 以下代码不可修改
list1 = input().split(",")
shift(list1)
print(list1)

虽然成功解决了问题,但是在子作用域中声明全局变量是非常不合适的,本来,我以为,在子域的变量,必须使用return来输出,不然就会困在子域中,无法被访问。但是下面这个例子显然驳斥了我的观点:

观察现象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def Mylst(lst)	# 子函数中的lst换成lst_1,最终也会导致全局中的lst被修改
ap = [1,2,3,4]
lst.append(ap)
print(lst)
# 在子域读取lst值,内置访问
return None

lst = ['a','b','c'] # 全局中的值
Mylst(lst) # 《《——
print(lst)
# 在全局调用函数,传入参数lst
# 在全局访问lst,外置访问

"""结果如下
['a','b','c',[1,2,3]]
['a','b','c',[1,2,3]]
"""

这是个菜鸟编程的样例,显然,样例中并没有使用return的方式来回传结果【箭头位置】,而直接在全局域中访问lst并且打印出了子域的值,而不是全局域中的值,你可能觉得,子域和全局域都使用了同一个变量名lst导致了巧合,实际上,将Mylst函数的形参换成A或者FCUK或者别的什么东西,结果是一样的,提出两个猜想:

1.全局域中,可以访问子域变量,且优先访问子域变量

2.函数直接对全局的lst进行了修改,并且从某种方式正确返回值

显然,学习了上一节,你可以知道,函数只能访问本域及各层父域的变量,不可能访问子域变量

因此,函数确实对传入的参数lst本身进行了修改

合理的解释?

经过我的查找,发现了Python函数参数传入的 可变对象传递不可变对象传递,感觉有点抽象和深奥,在此简单说明一下,其他可参考Blog

可变对象和不可变对象

可变对象就是可迭代对象,比如 字典、列表、集合

不可变对象就是不可迭代对象,如 字符串、数字、元组、函数本身

参数传入

可变对象作为参数传入时,实际上是这个变量指针对象本身传入,不对对象进行拷贝操作,因此在子函数内部对这个传入参数的修改,就是对这个变量指向的对象本身的修改。

我认为,在可变对象传入时,形参会把指针指向这个变量指针指向的对象本身。使用id( )去检测子函数的形参和传入参数的ID,返回值是一样的,因此在子函数中对对象的修改不需要经过返回值即可直接影响到父域的可变对象本身,因为父域的可变变量指针指向的对象本身被修改了,因此它的值也修改了。

传入不可变对象时,刚刚传入时,形参和父域变量的ID值是一样的,一旦要对其进行操作,比如 赋值等,因为对象本身不可变(1就是1,100就是100嘛),因此会深度拷贝该父域变量,赋值给形参,再对形参所指向的对象进行操作,最终结果不会直接影响到父域变量本身,且此时形参的ID值和父域变量不再一样。因此我认为此时就必须使用return将计算的结果传出。

使用以下两个小实验能有助于理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var = [1,2,3]	# 可迭代对象

def ischage(T):
print(id(T))
T[0] += 1
ischange(var)
print(id(var))
print(var)

"""
可以发现,形参T和实参var的ID值都一样,说明他们的指针都指向一个对象
在子函数中对T修改,就是对这个对象进行修改
意味着var也被修改了
"""

cont = 100
def ischange(S):
print(id(S))
S += 1
print(id(S))
ischange(cont)
print(id(cont))
print(cont)

"""
可以发现,形参S第一次ID值跟实参是一样的,但是第二次时就发生了改变
说明形参S已经拷贝了实参的值并对其新的对象内容进行修改
这个修改不会对实参造成影响,必须使用return来返回这个计算结果
"""

关于参数传递问题的续:

上面的论述都还没有完全解决HZH同志提出的问题,题目的意思肯定不是让我们用这么恶臭和不合规范的再子域中声明全局变量的写法。因此我们有必要进行进一步探索,实际上也不困难。

地址被偷换了

按照Dustella所述,使用list( )函数相当于深拷贝这个对象然后转换成列表,地址的变换在调用list( )时就不可避免了,我们的解决方案就是不调用list。

函数的写法

Dustella给出了多样的写法,开拓了大家的眼界。

1
2
3
4
5
6
7
8
def shift(ls:list) -> None :
end = ls.pop()
ls.insert(0,end)

# can not modify
list1 = input().split(",")
shift(list1)
print(list1)

其中,shift( ls : list )的意思是,直接告诉函数,传入的ls是个列表list,这样就不必调用list( )函数导致地址改变了

其中的 -> None是祂的习惯性写法,没有实质性作用(对Python来说)

===========================

基于上述理论,能给出更多的写法。

1
2
def shift(ls : list) -> None:
ls.insert(0,ls.pop())

使用pop()方法删除元素,本身就会返回被删除的元素的性质,可以缩减代码

1
shift = lambda ls : ls.insert(0,ls.pop())

使用匿名函数的方法,这样shift既可以接受参数,又不用写得特别庞大,真乃神来之笔

Data:2022-05

使用双重解析组合列表

可以使用二重解析,将两个列表以对应位置的元素形成元组再组合成列表

1
2
3
l1 = [1,2,3,4]
l2 = ['a','b','c','d']
l3 = [(m,n) for m in l1 for n in l2 ]

有点类似于字典推导,字典推导复习部分:

1
2
3
4
5
6
l1 = [(1,'a'),(2,'b')]
C = {name:value for name,value in l1}

l2 = [1,2,3,4]
l3 = ['a','b','c','d']
C2 = dic(zip(l2,l3))

关于列表的随机元素抽取

提供两种方法随机访问列表中的元素

1
2
3
4
5
6
7
8
9
10
lst = [1,2,3,4]

import random
C = lst[random.randint(0,len(lst))]

# 实际上使用一个包可以更快
from random import choice
choice(lst) #随机选取一个元素
choices(lst,k=3) #随机选取K个元素
sample(lst,k=3) #随机选取K个元素,且不重复

字典的一些用法

使得字典按照Key的大小降序排列

1
2
3
4
5
6
7
dic = {'a':2,'c':1,'b':3}
sort_by_key = sorted(dic.items(),key = lambda x:x[0],reverse=False)
dic_change = {key:value for key,value in sort_by_key}

# 与本文第一个关于字典内部排序的方法不同之处在于,第一个方法是对列表内嵌字典的元素进行排序
# 这个方法是对字典本身进行排序,先将字典的所有键值对以元组返回,然后对元组的第一个值,就是键进行排序
# 而后将所有元组再使用双重解析的方式遍历成字典

那么,按照类似的方法,我们也可以对值进行降序排列,尝试实现一下?

1
2
3
dic = {'a':4,'b':2,'c':3,'d':1}
sort_by_value = sorted(dic.items(),key = lambda x:x[1],reverse=False)
dic_change = {key:value for value,key in sort_by_value}

字典合并<2>

对于两个字典,合并方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dic_1 = {'name':'Dustella','big':1}
dic_2 = {'name':'DUstella','sex':100}

# 使用update更新
dic_3.update(dic_2)

# 使用双重解析更新字典(字典推导式)
dic_4 = {key:value for dic in [dic_1,dic_2] for key,value in dic.items()}

# 元素拼接发
dict(list(dic_1.items()) + list(div_2.items()))

# chain()可以将序列连接并返回可迭代对象
from itertools import chain
dict(chain(dic_1.items(), dic_2.items()))

# 字典解包法
{**dic_1, **dic_2}

奇奇怪怪

赋值与二元操作符

存在这样一种代码(魔法师说是一种语法糖),按位与并把结果赋值,如下:

1
2
3
4
5
a = 0b1000
b = ob1010
# 1&1 == 1 only
a &= b
print(a)

也就是说,只有当a、b的位都是1时才能为1,否则均为0

同样的,还有按位或,并赋值 a |= b,也有异或a ^= b

均等于他们的原来形式,比如a &= b == a = a&b

enumerate()编制索引

enumerate函数将可迭代对象编辑索引,并且遍历时会同时返回索引

实现如下

1
2
3
4
5
6
7
8
9
10
lst = ['a','b','c']
for indx, chr in enumerate(lst):
print(indx, chr)
# 结果
'''
0 a
1 b
2 c
'''

迭代器检验

使用any( )可以检验迭代对象内容的布尔值,当全为False时返回False,空迭代对象也返回False

使用all( )可以检验迭代对象的元素布尔值,全为True时返回True,否则返回False

一些奇特的方法

去掉0x、0b等

输入一个数,将它转换成十六进制并输出,居中,以填充字符,限制为10字符长度,实现如下:

1
2
3
4
5
6
7
8
9
10
s = input()
# 转换成十六进制
s_2 = hex(eval(s))
# 标准化输出,同时截去头部的0x
print("{:\"^10}".format(s_2[2:]))
# 使用 \ 转义其中的 “

# 简写如下
s = input()
print("{:\"^10}".format(hex(eval(s))[2:]))

字符串操作

输入一个中文数字(〇一二三……)将其替换成数字(0123……),要求原地代码。

给出固定格式代码,只能在横线____处添加一行代码实现功能

1
2
3
4
5
n = input()
s = "〇一二三四五六七八九"
for i in s:
# ________
print(n)

因为是原地代码而且只能使用一行,因此只能使用str.replace(old,new)的方式来替换字符

实现如下

1
2
3
4
5
n = input()
s = "〇一二三四五六七八九"
for i in "0123456789":
n = n.replace(i,s[int(i)])
print(n)

关于函数奇妙写法(函数解释器)的再探讨

前文我们提到了,在写函数的时候,有人写了这个写法

1
2
def function(A,B:list) -> None:
Pass

之前的解释是,B:list是告诉函数这个参数是列表,但是->None是祂的一种习惯写法。

之后又遇到了更加离谱的写法,如下:

1
2
def super_function(A:list=[],B:'int>10'=12) -> str:
Pass

WTF,这么复杂的写法,肯定不仅仅是习惯问题了,一定是存在某个规则,因此我去查阅了一些资料,得到如下结论:

这些写法其实是函数解释器,用来告诉函数每个参数是什么东西,有哪些限制,返回值是什么类型,这种写法在静态语言里面是强制的,比如C和Java,但是对于动态语言Python来说,是不强制、不检查的,因为编译器会在遇到这个变量赋值自动判断它的类型,使得py没有那么多硬性的复杂语法,相比于C简洁很多,但不严格意味着错误概率提升,py的隐式转换有时候会导致整个程序的致命错误,难以调试,而C的严格限制变量的类型则会在编译的时候就发现错误。

虽然提供解释器,但是py也是不检查、不要求的,这么写是为了让读程序的人查看方便(或者更难理解?)

总之这么写是一种好的习惯。

现在来解释具体含义:

A:list=[]:传入参数A是一个列表,默认是空列表

B:”int>10”=12:传入参数B是一个大于10的整数,默认值为12

-> str:整个函数的返回值应该是字符类型

文件操作

示例一

给出一个关于星座内容的.CSV文件,文件固定格式为序号,星座,开始日月,结束日月,Unicode,例如第二行内容为1,水瓶座,120,218,9810。完成第一个任务

当用户输入星座名,如 双子座时返回双子座的生日位于521-621之间,给出格式化输出的代码,剩下的请自行完成。

1
print("{}的生日位于{}-{}之间".format(……))# …… 中的代码请自行补全

思路:

CSV是多行文件,本来想读一行判断一行,但是实现起来有点困难,决定一次性把多行读取,存入一个列表中,再通过遍历访问来判断。

实现如下:

1
2
3
4
5
6
7
8
9
# -*- coding:utf-8 -*-
f = open("./PY301-SunSign.csv","r")
tar = input("请输入星座的名称(例如,双子座)")
lst = []
for i in [x.decode("utf-8") for x in f.readlines()]:
lst.append(i.split(","))
for j in lst:
if j[1] == tar:
print("{}的生日位于{}-{}之间".format(j[1],j[2],j[3]))

如果在 open()内直接说明open(encoding=“utf-8”)且使用r模式,for语句就不需要解码指令了。当然,指定解码模式只能使用r打开,使用rb打开会报错

复盘:

■使用r方式打开会报解码错误,必须立即指明解码方式encoding="utf-8"使用rb模式再解码不会报错

■使用r模式访问readline()返回的是奇怪的一串东西(如果没有在open设置解码的话)

readlines()返回以每一行字符串组成的列表,需要把字符串进一步转换成列表才能被访问,否则访问会存在一些困难

■如果使用列表解析式[list(x) for x in f.readlines()]尝试把readlines返回的列表内部的字符串转换成列表,最终会得到每个字符单独组成的字符串所组成的列表。如下形式:

[['序', '号', ',', '星', '座', ',', '开', '始', '月', '日', ',', '结', '束', '月', '日', ',', 'U', 'n', 'i', 'c', 'o', 'd', 'e', '\n'], ['1', ',', '水', '瓶', '座', ',',………………]

示例二

给一个文本vote.txt,里面一行应有一个明星的名字,要求对里面的明星得票进行统计,多写或不写不计入结果,多写的均以单个空格隔开。

给出示例代码,在横线仅填写一行代码:

1
2
3
4
5
6
7
8
9
10
11
12
f = open("vote.txt",encoding="utf-8")
names = f.readlines()
f.close()
D = {}
for name in _______(1)_________:
if len(_____(2)______)==1:
D[name[:-1]]=_______(3)_________ + 1
l = list(D.items())
l.sort(key=lambda s:s[1],_______(4)_________)
name = l[0][0]
score = l[0][1]
print("最具人气明星为:{},票数为:{}".format(name, score))

答案如下:

1
2
3
4
5
6
7
8
9
10
11
12
f = open("vote.txt",encoding="utf-8")
names = f.readlines()
f.close()
D = {}
for name in names:
if len(name.split())==1:
D[name[:-1]]=D.get(name[:-1],0) + 1
l = list(D.items())
l.sort(key=lambda s:s[1],reverse=True)
name = l[0][0]
score = l[0][1]
print("最具人气明星为:{},票数为:{}".format(name, score))

本题不难,现在解释一部分内容:

open默认使用r读取,因此必须加入encoding=“utf-8”

将文本多行读取后记得使用close()将其关闭,释放空间

readlines()返回的是每一行内容组成的字符串“XXXX”组成的列表,比如[“孙俪\n”,“周杰伦 孙俪\n”,“周杰伦\n”……]

for name in names后,name的值为字符串,统计时必须使用name[:-1]来把明星的名称全部录入,使用name[0]只会录入姓氏造成统计故障

将最终的字典以元组形式返回,再形成列表,然后用lambda辅助进行排序,记得reverse=True因为默认排序是从小到大的,然后再访问即可。

编码问题:

大多数时候使用utf-8解码,等价于CHCP65001编码

GB2132等价于cp936编码

这些个数字只是中文系统里的编号而已

BGK兼容GB2132


Python学习笔记-总
https://qlozin.top/2022/04/19/Python学习笔记/
作者
QLozin
发布于
2022年4月20日
更新于
2024年8月11日
许可协议