Python基础知识
Posted gugu-da
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python基础知识相关的知识,希望对你有一定的参考价值。
Python 基础知识
1.语言特征及编码规范
1.1 Python 的解释器有哪些?
- CPython:采用 C 语言开发的的一种解释器,目前最通用也是使用最多的解释器。
- IPython:是基于 CPython 之上的一个交互式解释器器,交互方式增强功能和 CPython 一样。
- PyPy:目标是执行效率,采用 JIT 技术。对 Python 代码进行动态编译,提高执行的速度。
- JPython:基于 Java 语言的解释器,可以直接将 Python 代码编译成 Java 字节码执行。
- IronPython:运行在微软 .NET 平台上的解释器,把 Python 编译成 .NET 的字节码,然后执行。
1.2 列举至少 5 条 Python 3 和 Python 2 的区别?
- Python 3 中默认使用是 UTF-8 编码,在 Python 3 版本中的中文字符是合法的。
- Python 2 中默认使用 xrange,Python 3 已经改成了 range。
- Python 3 中的 print 输出函数,需要使用括号,Python 2 中 print 为 class,不需要使用。
- Python 2 中默认的字符串类型默认是 ASCII,Python 3 中默认的字符串类型是 Unicode。
- Python 2 中除法/的返回的结果是整型,Python 3 中返回的结果是浮点类型。
- Python 2 中声明元类:
_metaclass_ = MetaClass
,Python 3 中声明元类:class newclass(metaclass=MetaClass):pass
。 - 异常:在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用 as 作为关键词。捕获异常的语法由
except exc, var
改为except exc as var
。 - 不等运算符:Python 2.x 中不等于有两种写法
!=
和<>
,Python 3.x中去掉了<>
,只有!=
一种写法,还好,我从来没有使用<>
的习惯。 - zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。
- Python 2 和 Python 3 中还有很多方法返回的是一个可迭代对象,并不是列表。
1.3 Python 中新式类和经典类的区别是什么?
在 Python 3 版本中已经取消了经典类,默认都是新式类,并且不必显式的继承 object,以下三种类的写法一样:
class Fruit(object):
pass
class Fruit():
pass
class Fruit:
pass
在 Python 2 版本中,默认都是经典类,只有继承了 object 才是新式类,参考以下三种写法:
# 新式类写法
class Fruit(object):
pass
# 以下两种为经典类写法
class Fruit():
pass
class Fruit:
pass
在 Python 2 版本中,经典类和新式类的主要区别:
- 经典类是采用的深度优先算法:当子类继承多个父类的情况时,如果继承的多个父类有属性相同的,根据深度优先,会以继承的第一个父类的属性为主;
- 新式类是采用的广度优先算法:当出现子类继承多个父类的属性相同时,由于采用广度优先算法,后面继承的属性会覆盖前面已经继承的属性。
1.4 Python 之禅是什么,Python 中如何获取 Python 之禅?
- 新建一个 Python 文件,通过
import this
可以获取 Python 之禅的具体内容; - Python 之禅目的是告诉我们如何写出高效整洁的代码;
- 其实也是 Python 语言的一种宗旨——简洁高效。
import this
# 具体输出的结果就是Python之禅
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren‘t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you‘re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it‘s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let‘s do more of those!
1.5 python中的DocStrings(解释文档)有什么作用?
DocStrings 的主要作用就是解释代码的作用,让其他人读你的代码时候,能更快速理解代码的作用是什么。
当定义一个函数后,我们可以在函数的第一行使用一对三个单引号 ‘‘‘
或者一对三个双引号 """
来定义一个文档字符串,该文档字符串就是该函数的解释文档。
使用 doc(注意双下划线)调用函数中的文档字符串属性(注意,文中出现的反斜杠是转义符,去除一些符号的特殊格式)。
def get_max(x,y):
‘‘‘
比较取出两个int类型中较大的那个数
:param x: int类型数字
:param y: int类型数字
:return: 输出较大值
‘‘‘
if x > y:
return x
else:
return y
get_max(3, 5)
print(get_max.__doc__) # 输出解释文档的具体内容
1.6 Python 3 中的类型注解有什么好处?如何使用?
Python 是一种高级语言,在我们编写代码的时候,我们定义的变量和定义函数里面的参数的时候,是不用区分它们的类型。但是作为作者我们知道函数的参数应该传入什么类型的数据,但是作为读者并不能快速知道变量或者参数的类型是什么。
针对上述问题,我们就可以使用类型注解,类型注解的好处就是让读者快速知道我们变量或者参数的类型是什么。
参考以下代码
# 通用写法
def func(x, y):
return x + y
# 函数注解写法,表明传入的两个数字是int类型
def func(x:int, y:int) -> int:
return x + y
1.7 Python 语言中的命名规范有哪些?
基本原则:Python 语言的标识符必须以字母、下划线 _
开头,数字不能作为开头,后面可以跟任意数目的字母、数字和下划线 _
。此处的字母并不局限于 26 个英文字母,可以包含中文字符、日文字符等。
禁忌:Python 包含一系列关键字和内置函数,不建议使用它们作为变量名,防止发生冲突。
常用命名规则:
- 项目名:首字母大写、其余单词小写,多单词组合则用下划线分割
- 包名、模块名:全用小写字母
- 类名:首字母大写、其他字母小写,多单词采用驼峰
- 方法:小写单词
- 函数:若函数的参数名与保留关键字冲突,则在参数后加一个下划线,比拼音好太多
- 全局变量:采用全大写,多单词用下划线分割
注意:
- 不论是类成员变量还是全局变量,均不使用 m 或 g 前缀。
- 私有类成员使用单一下划线前缀标识,多定义公开成员,少定义私有成员。
- 变量名不应带有类型信息,因为 Python 是动态类型语言。如 iValue、names_list、dict_obj 等都是不好的命名。
- 开头、结尾一般为 Python 的自有变量,不要以这种方式命名
- 以
__
开头(2 个下划线),是私有实例变量(外部不嫩直接访问),依照情况进行命名。
1.8 Python 中各种下划线的作用?
关于下划线:
- 一个前导下划线:表示非公有,也叫做保护变量,表示类对象和子类对象自己才能访问这些变量。采用
from somemodulename import *
的方法导入模块时,被保护的变量不会被导入。 - 一个后缀下划线:为了避免关键字冲突,采用的一种命名方法。
- 两个前导下划线:私有属性,当命名一个类属性可能引起名称冲突时使用。避免与子类中的属性命名冲突,无法在外部直接访问(名字已经被重整所以访问不到),类对象和子类可以访问(公有方法可以间接访问,使用重整后的名称访问)。
- 两个前导和后缀下划线:内置的的魔法对象或者属性(有特殊用途),例如 init 或者 file。我们不要自己创造类似的名称,只需要使用他们即可。
补充:
- 私有属性和私有方法使用双前置下划线,私有属性和方法类内部,类的对象和子类可以访问
- 私有属性和私有方法外部不能直接访问
- 单前置下划线是普通方法
- 父类的私有属性和私有方法
- 子类对象不能在自己的方法内部,直接访问父类的私有属性或私有方法
- 子类对象可以通过父类的公有方法间接访问到私有属性或私有方法
私有属性本质:
- 类创建的时候,在 init 方法中,采用双前置下划线创建的属性,该属性创建后,类内部实际上对该属性进行了名字重整(改名了,私有方法和属性在外部不可以直接用属性或方法名调用,内部将私有方法和属性在前面增加了
"_类名"
)。 - 因此实例化对象后,外界访问不到,但是使用重整后的名字可以访问。
1.9 单引号、双引号、三引号有什么区别?
- 单引号和双引号:单独使用单引号和双引号没什么区别,但是如果引号里面还需要使用引号的时候,就需要这两个配合使用了。一般建议外部使用单引号,内部使用双引号。
- 三引号:三引号也分为三单引号和三双引号,一般用于函数功能描述。两个都可以声名长的字符串时候使用,如果使用 docstring 就需要使用三双引号。
- 推荐:三个单引号或者双引号常用于文档注释,推荐使用三个单引号。
- 推荐:双引号,纯粹的字符串,用于打印显示,字符串的拼接,使用双引号;单引号,除了纯粹的字符串,其它的字符串、参数等都用单引号,比如字典的键值、类传入的参数等等。
2. 文件 I/O 操作
2.1 Python 中打开文件有哪些模式?
参考以下表格,‘+‘ 可读写模式(可添加到其他模式中使用):
type | info |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
2.2 Python 中 read 、readline 和 readlines 的区别?
- read():read 表示一次性将文件的所有内容都读取到内存之中,如果文件占用空间很大,一次性读取出出现内存不足的问题。针对文件过大,内存不足的问题,我们可以使用,read(size) 一次最多读取多少的 size 字节,读取大文件时候可以多次调用该方法。
- readline():每次只读取一行的内容,如果是文本文件,建议使用该方法,一次读取一行,逐行读取。
- readlines():和 read() 方法一样,也是一次读取所有的内容,但是返回结果不同,该方法是按行读取后返回的一个列表,可以使用for循环取出列表中每个元素,一个元素就代表一行。
2.3 大文件只需读取部分内容,或者避免读取时候内存不足的解决方法?
方法 1:直接 for 循环迭代协议,避免内存不足,但是使用 with 打开文件后会自动关闭,需要再次打开。
# 注意:filetest.txt是一个有多行文字的一个文档,可以自己创建一个txt文档打开
with open(‘filetest.txt‘, ‘r‘) as f:
for line in f:
print(line)
方法 2:迭代器切片操作,使用 islice。
# islice返回一个生成器函数,进行切片操作,取出索引为101到105的值
with open(‘filetest.txt‘, ‘r‘) as f:
for line in islice(f, 101, 105):
print(line)
for line in islice(f, 5): #只给一个参数,指定的是结束的位置
print(line)
2.4 什么是上下文?with 上下文管理器原理?
with 方法常用于打开文件,使用 with 方法打开文件后可以自动关闭文件,即使打开或者使用文件时出现了错误,文件也可以正常关闭。
什么是上下文(context)?
- context 其实说白了,和一篇文章中的上下文是一个意思,在通俗一点,我觉得叫环境更好。
- 上下文虽然叫上下文,但是程序里面一般都只有上文而已,只是为了叫的好听叫上下文。
- 进程中断在操作系统中是有上有下的,不过不这个高深的问题就不要深究了
- 任何实现了 enter() 和 exit() 方法的对象都可以称之为上下文管理器,上下文管理器对象可以使用with关键字。显然,文件(file)对象也实现了上下文管理器。
那么文件对象是如何实现这两个方法的呢?我们可以模拟实现一个自己的文件类,让该类实现 enter() 和 exit() 方法。
‘‘‘
Author: Felix
WX: AXiaShuBai
Email: xiashubai@gmail.com
Blog: https://blog.csdn.net/u011318077
Desc:
‘‘‘
# 文件管理器
class File():
# 初始化方法
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
# 打开文件的方法,返回我们打开的对象,也就是传入的文件
def __enter__(self):
print("entering")
self.f = open(self.filename, self.mode)
return self.f
# 关闭文件的方法,不用我们自己手动去关闭文件对象了
def __exit__(self, *args):
print("will exit")
self.f.close()
with File(‘test.txt‘, ‘w‘) as f:
print("writing")
f.write(‘hello, world‘)
2.5 什么是全缓冲、行缓冲和无缓冲?
- 全缓冲:Python 中默认的缓冲区是 4096 字节,当缓冲区里面的空间占满后,就将数据写入到磁盘中。
- 行缓冲:当写入的数据,每遇到换行符,就将缓冲中的数据写入到磁盘中。
- 无缓冲:无缓冲,顾名思义就是一写入数据,就将数据写入到磁盘中。
- 三种缓冲,可以通过 buffering 参数进行设置。
# -*- coding:utf-8 -*-
# python中默认的缓冲区(全缓冲)是4096字节
# buffering可以设置缓冲字节大小,当写入的数据超过设置值,才会写入到文件中
f = open(‘001_测试缓冲案例文件.txt‘, ‘w‘, buffering=2048)
# 写入3个字节,打开txt文件为空
f.write(‘abc‘)
# 写入2045个字节,总共2048个,还是为空
f.write(‘*‘ * 2045)
# 此时我们在写入一个字节,就由缓冲存储到磁盘了,此时打开txt文件就可以看见数据了
# 行缓冲: buffering=1
# f = open(‘001_测试缓冲案例文件.txt‘, ‘w‘, buffering=1)
# f.write(‘abc‘)
# 只要遇到换行符,就将缓存存到磁盘
# f.write(‘
‘)
# 无缓冲:buffering=0
# 写入数据就直接存储到磁盘
2.6 什么是序列化和反序列化?JSON 序列化时常用的四个函数是什么?
什么是序列化:我们程序中的变量和对象(比如文字、图片等内容),在传输的时候需要使用二进制数据,将这些变量或对象转换为二进制数据的过程,就是序列化。
什么是反序列化:反序列化就是序列化的逆过程,把获取的二进制数据重建为变量或对象。实际序列化和反序列化就是二进制数据和原始数据格式之间的一个转换过程。
JSON 中常用的四个函数:
- json.dump:将数据序列化到文件中
- json.load:将文件中的内容反序列化读取出来
- json.dumps:将 Python 格式转化为 JSON 的字符串形式(序列化)
- json.loads:将 JSON 的字符串格式转换为 Python 的数据格式(反序列化)
- 上面容易混淆,记住 load 是下载的意思,就是将 JSON 的读取出来或者转换为 Python 的数据格式;dump 是倾倒,意思就是把数据放进去,正好和 load 相反。
注意:标准 JSON 格式数据要使用双引号。
2.7 JSON 中 dumps 转换数据时候如何保持中文编码?
可以通过 json.dumps 的 ensure_ascii 参数解决,代码示例如下:
# file = open(‘papers.json‘, ‘w‘, encoding=‘utf-8‘)
# 将item字典类型的数据转换成json格式的字符串,
# 注意json.dumps序列化时对中文默认使用的ascii编码,要想写入中文,加上ensure_ascii=False
# line = json.dumps(dict(item), ensure_ascii=False) + "
"
# file.write(line)
import json
a=json.dumps({"python":"你好"},ensure_ascii=False)
print(a)
# {"python":"你好"}
3. 数据类型
3.1 Python 中的可变和不可变数据类型是什么?
我们可以判断对象的内存地址是否变化类确定数据的类型:
- 可变数据类型:数据的值改变,对象的 id 值不变;
- 不可变数据类型:数据的值改变,对象的 id 值也随之改变。
如何确定一种数据类型是可变的还是不可变的,在改变 value 值的同时,使用 id() 函数查看变量 id 值是否变化即可。
注意:字典是可变类型,但是字典中的 key 是不可变类型。
数据类型 | 可变/不可变 |
---|---|
整型 | 不可变 |
字符串 | 不可变 |
元组 | 不可变 |
列表 | 可变 |
集合 | 可变 |
字典 | 可 |
3.2 is 和 ==
有什么区别?
- is:把两个的对象的 id 值进行比较,看它们是否相等,是否指向同一个内存地址,如果 id 值相等,就是同一个实例对象。
==
:把两个对象的内容或者值拿出来比较,调用的是 eq() 方法,值如果相等就是 true,但是它们的 id 不一定相同。
3.3 Python 中的单词大小写转换和字母统计?
- 每个单词首字母大写:title()
- 句子第一个字母大写:capitalize()
- 所有字母大写小写:upper()、lower()
- 统计某个字母出现的次数:count(‘h‘)
3.4 字符串,列表,元组如何反转?反转函数 reverse 和 reversed 的区别?
- reverse:是列表反转的一个方法,用于整个列表元素顺序反转排列。
- reversed:也是一个反转的方法,但是返回的不是一个列表,而是一个迭代器,只要是可迭代对象,都可以使用该方法进行反转。反转后的迭代器可以使用 for 循环或者 next 方法取出元素。
# reverse列表反转
ls1 = [1, 2, 3]
ls1.reverse()
print(ls1)
# reversed: reversed()的作用之后,返回的是一个把序列值经过反转之后的迭代器,
ls2 = [4, 5, 6]
print(reversed(ls2)) # 迭代器对象的内存地址
print(list(reversed(ls2)))
# 字符串反转方法1
str1 = ‘abced12345‘
str2 = ‘‘.join(reversed(str1)) # 使用join拼接反转后的字符
print(str2)
# 字符串反转方法2
str3 = str1[::-1]
print(str3)
# 输出结果:
# [3, 2, 1]
# <list_reverseiterator object at 0x0003545427A5454682E8>
# [6, 5, 4]
# 54321decba
# 54321decba
3.5 Python 中的字符串格式化的方法有哪些?f-string 格式化知道吗?
- %s:s 代表字符串
- %d:d 代表数字
- %.2f:数字保留 2 位小数
- {}.format()
- f-string:Python 3.6 才开始支持,更加简洁
具体使用参考下面代码:
# %s
message = ‘I love %s‘ % (Chengdu)
print(message) # I love Chengdu
# format
message = ‘I love {}‘.format(Chengdu)
print(message) # I love Chengdu
# f-string
res= f"{2 * 3}"
print(res) # 6
student = {‘name‘: ‘Felix‘, ‘age‘: 20}
res1 = f"The student is {student[‘name‘]}, aged {student[‘age‘]}."
print(res1)
# ‘The student is Felix, aged 20.‘
3.6 含有多种符号的字符串分割方法?
- 方法 1:使用
[]+
,中括号里面写上所有的符号,后面的+
表示可以出现多次,类似于正则表达式 - 方法 2:使用竖线
|
表示或
# 含有多种分隔符分割
s = ‘ab;cd%e fg,,jklioha;hp,vrww yz‘
# 方法1,使用中括号:
# 正则表达式分割,推荐使用
import re
# 将多个分隔符直接写在正则表达式中,使用中括号,后面的+号表示前面的符号可以出现多次
t = re.split(r‘[;%, ]+‘, s)
print(t)
# [‘ab‘, ‘cd‘, ‘e‘, ‘fg‘, ‘jklioha‘, ‘hp‘, ‘vrww‘, ‘yz‘]
# 方法2:使用|表示或
s="info:xiaoZhang 33 shandong"
res = re.split(r‘:| ‘, s)
print(res)
# [‘info‘, ‘xiaoZhang‘, ‘33‘, ‘shandong‘]
3.7 嵌套列表转换为列表,字符串转换为列表的方法
嵌套列表到列表,双 for 循环:
# 嵌套列表到单层列表
l1 = [[1,2],[3,4],[5,6]]
# 先从列表l1中取出每个列表i,然后从每个列表i中取出元素j,然后由j生成一个新的列表
l2 = [j for i in l1 for j in i]
print(l2)
# 字符串到列表,使用逗号分隔,如果只是单纯的字符串,直接使用list就可以生成列表
s1 = ‘a,b,c,1,2,3‘
l3 = s1.split(‘,‘)
print(l3)
# [1, 2, 3, 4, 5, 6]
# [‘a‘, ‘b‘, ‘c‘, ‘1‘, ‘2‘, ‘3‘]
3.8 列表合并的常用方法?
- 使用 extend 方法扩展列表
- 使用加号,两个列表相加,会合并为一个列表
- for 循环取出,然后使用 append 方法,将一个列表元素添加到另外一个列表中
3.9 列表如何去除重复的元素,还是保持之前的排序?
使用 set 集合和 sorted 排序,参考代码:
l = [‘1‘, ‘5‘, ‘1‘, ‘3‘, ‘3‘,]
def list_new(l):
# 先使用set生成一个集合,会自动删除掉重复的元素
# 使用sorted排序,排序还是按照以前的索引值
list_new = sorted(set(l), key=l.index)
print(list_new)
list_new(l)
# [‘1‘, ‘5‘, ‘3‘]
3.10 列表数据如何筛选,筛选出符合要求的数据?
- for 循环,筛选出符合条件的数据,添加到一个空列表中
- 过滤函数 filter 配合匿名函数 lambda 表达式
- 列表解析(推荐使用,效率最高)
‘‘‘
Author: Felix
WX: AXiaShuBai
Email: xiashubai@gmail.com
Blog: https://blog.csdn.net/u011318077
Desc:
‘‘‘
# 列表筛选:
# 方法1:使用过滤函数filter
from random import randint
import time
data = [randint(-10, 10) for _ in range(10)]
print(data)
print("*" * 100)
# 过滤函数:符合条件的就留下,使用list生成一个列表
res = list(filter(lambda x: x >= 0, data))
print(res)
print("*" * 100)
# 方法2:列表解析,速度更快,推荐使用
start =time.time()
res = [x for x in data if x >= 0]
end = time.time()
print(‘Running time: %s Seconds‘%(end-start))
print(res)
# [5, -6, -10, 3, -4, -6, -9, 10, -3, -1]
# ****************************************************************************************************
# [5, 3, 10]
# ****************************************************************************************************
# Running time: 0.0 Seconds
# [5, 3, 10]
3.11 字典中元素的如何排序?sorted 排序函数的使用详解?
- 使用 sorted 排序函数:第一个参数是一个可迭代对象,第二个参数 key 传入排序的规则,使用 lambda 表达式,第三个参数 reverse,默认是 False,可以传入 True 代表倒序排列
- lambda 表达式传入的规则可以传入一个元组包含多个规则,规则中进行判断,不满足的就是 False,排在在后
‘‘‘
Author: Felix
WX: AXiaShuBai
Email: xiashubai@gmail.com
Blog: https://blog.csdn.net/u011318077
Desc:
‘‘‘
d1 = [
{‘name‘:‘alice‘, ‘age‘:38},
{‘name‘:‘bob‘, ‘age‘:18},
{‘name‘:‘Carl‘, ‘age‘:28},
]
# 排列列表中字典,直接排列字典也是相同的方法
# 默认reverse=False
d2 = sorted(d1, key=lambda x: x[‘age‘])
print(d2)
# 倒序,传入reverse=True
d3 = sorted(d1, key=lambda x: x[‘age‘], reverse=True)
print(d3)
# 也可以传入索引值,用于排序
students = [(‘john‘, ‘A‘, 15), (‘jane‘, ‘B‘, 12), (‘dave‘,‘B‘, 10)]
d4 = sorted(students,key=lambda x: x[2])
print(d4)
# [{‘name‘: ‘bob‘, ‘age‘: 18}, {‘name‘: ‘Carl‘, ‘age‘: 28}, {‘name‘: ‘alice‘, ‘age‘: 38}]
# [{‘name‘: ‘alice‘, ‘age‘: 38}, {‘name‘: ‘Carl‘, ‘age‘: 28}, {‘name‘: ‘bob‘, ‘age‘: 18}]
# [(‘dave‘, ‘B‘, 10), (‘jane‘, ‘B‘, 12), (‘john‘, ‘A‘, 15)]
# 先看一下Boolean value 的排序:
# Boolean 的排序会将 False 排在前,True排在后
print(sorted([True,False]))
s = ‘abC234568XYZdsf23‘
# 排序规则:小写<大写<奇数<偶数
# 原理:先比较元组的第一个值,FALSE<TRUE,如果相等就比较元组的下一个值,以此类推。
print("".join(sorted(s, key=lambda x: (x.isdigit(), x.isupper(), x.isdigit() and int(x) % 2 == 0, x))))
# False排在后面
# 1.x.isdigit()的作用是把字母放在前边,数字放在后边.
# 2.x.isdigit() and int(x) % 2 == 0的作用是保证奇数在前,偶数在后。
# 3.x.isupper()的作用是在前面基础上,保证字母小写在前大写在后.
# 4.最后的x表示在前面基础上,对所有类别数字或字母排序。
# 同时满足上面的规则
list1=[7, -8, 5, 4, 0, -2, -5]
# 要求1.正数在前负数在后 2.整数从小到大 3.负数从大到小
# 先按照正负排先后,再按照大小排先后
print(sorted(list1,key=lambda x:(x<0, abs(x))))
# x<0,表示负数在后面,正数在前面
# abs(x)表示按绝对值,小的前面,大的在后面
# [False, True]
# abdfsCXYZ33522468
# [0, 4, 5, 7, -2, -5, -8]
代码中部分案例引用来源(CSDN 博客):https://blog.csdn.net/u013759354/article/details/80243705
3.12 字典如何合并?字典解包是什么?
- 字典合并:a.update(b)
- 字典解包 {a,b}
# 方法1:
# 使用update方法,将b字典添加到a中,类似于列表的append方法
a = {"A": 1,"B": 2}
b = {"C": 3,"D": 4}
a.update(b)
print(a)
# 方法2:
# 使用字典解包
a = {"A": 1,"B": 2}
b = {"C": 3,"D": 4}
print({**a})
print({**a,**b})
# {‘A‘: 1, ‘B‘: 2, ‘C‘: 3, ‘D‘: 4}
# {‘A‘: 1, ‘B‘: 2}
# {‘A‘: 1, ‘B‘: 2, ‘C‘: 3, ‘D‘: 4}
3.13 字典推导式使用方法?字典推导式如何格式化 cookie 值?
- 字典生成式和列表生成式一样,都是使用 for 循环,可以多层 for 循环嵌套
- 字典的键值交换:
{v: k for k,v in d.items()}
- 字典生成式常用于 cookie 值转换为字典格式
# 字典键值交换
d = {‘a‘: ‘1‘, ‘b‘: ‘2‘, ‘c‘: ‘3‘}
print({v: k for k,v in d.items()})
# 字典推导式的常用于格式化cookie值:
# 字符串分割后得到字典
cookies = "anonymid=k06r6sdauyh36v; depovince=ZGQT; _r01_=1; JSESSIONID=abcOraT1E7z0JhHDATb0w; ick_login=8f53ebf1-b972-4572-8f77-810953dcfdfe; first_login_flag=1; ln_uact=55555835@qq.com;loginfrom=null; wp_fold=0"
# 使用字典推导式将上述字符串转化为一个字典, 先使用;分割得到一个列表,
# 列表中每一个元素再用=进行分割,列表第一个值为键,第二个值为值
cookies ={i.split("=")[0]: i.split("=")[1] for i in cookies.split(";")}
print(cookies)
# {‘1‘: ‘a‘, ‘2‘: ‘b‘, ‘3‘: ‘c‘}
# {‘anonymid‘: ‘k06r6sdauyh36v‘, ‘ depovince‘: ‘ZGQT‘, ‘ _r01_‘: ‘1‘, ‘ JSESSIONID‘: ‘abcOraT1E7z0JhHDATb0w‘, ‘ ick_login‘: ‘8f53ebf1-b972-4572-8f77-810953dcfdfe‘, ‘ first_login_flag‘: ‘1‘, ‘ ln_uact‘: ‘55555835@qq.com‘, ‘loginfrom‘: ‘null‘, ‘ wp_fold‘: ‘0‘}
3.14 zip 打包函数的使用?元组或者列表中元素生成字典?
- zip() 函数,传入可迭代对象作为参数,然后元素一一对应组成一个元组,然后所有元组打包为一个列表。
- zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。
# zip函数用于打包元素
# zip() 函数用于将可迭代的对象作为参数,
# 将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
# >>>a = [1,2,3]
# >>> b = [4,5,6]
# >>> zipped = zip(a,b) 打包为元组的列表
# [(1, 4), (2, 5), (3, 6)]
# 生成前后元素生成一个字典
l = [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘,‘f‘]
l1 = list(zip(l[:-1],l[1:]))
print(l1)
print(dict(l1))
# [(‘a‘, ‘b‘), (‘b‘, ‘c‘), (‘c‘, ‘d‘), (‘d‘, ‘e‘), (‘e‘, ‘f‘)]
# {‘a‘: ‘b‘, ‘b‘: ‘c‘, ‘c‘: ‘d‘, ‘d‘: ‘e‘, ‘e‘: ‘f‘}
3.15 字典的键可以是哪些类型的数据?
- 字典的键是可以被 hash 的,可以被 hash 的对象就是不可变数据,不可变数据可以作为字典的键,比如数字、字符串、元组都可以
- 列表、集合、字典是可变类型不是可 hash 对象,所以不能用列表做为字典的键
3.16 变量的作用域是怎么决定的?
- 在 Python 中,定义一个变量,该变量的作用域是该变量被赋值时候所处的位置决定的
- 当一个变量在函数内部被定义和赋值,该变量就是一个局部变量,在函数外部使用就会出现错误
- 函数变量作用域的搜索顺序:本地作用域(Local)、当前作用域被嵌入的本地作用域(Enclosing locals)、全局/模块作用域(Global)、内置作用域(Built-in)
4 常用内置函数
4.1 如何统计一篇文章中出现频率最高的 5 个单词?
统计单词出现的个数,使用 collections 中的 Counter 统计类:
‘‘‘
Author: Felix
WX: AXiaShuBai
Email: xiashubai@gmail.com
Blog: https://blog.csdn.net/u011318077
Desc:
‘‘‘
import re
from collections import Counter
# 英文文档案例.txt我们可以自己本地创建一个文档,或者网上下载一篇txt的英文文档都可以
# 读取整个文件为一个字符串,英文文档可以自己随便网上下载一个txt的文件
txt = open(‘英文文档案例.txt‘).read()
# 使用非字母对上面的字符串进行分割
res = re.split(r‘W+‘, txt)
# print(res)
# 统计每个单词出现的次数
c = Counter(res)
print(c)
print("*" * 100)
# 统计出现最多的5个单词
print(‘出现频率最高的5个单词:‘)
print(c.most_common(5))
print("*" * 100)
# Counter({‘the‘: 12, ‘and‘: 10, ‘can‘: 10, ‘to‘: 9, ‘in‘: 8, ‘mobile‘: 6, ‘we‘: 6, ‘is‘: 6, ‘us‘: 6, ‘more‘: 5, ‘a‘: 5, ‘of‘: 5, ‘it‘: 5, ‘phone‘: 4, ‘for‘: 4, ‘some‘: 4, ‘We‘: 4, ‘information‘: 3, ‘make‘: 3, ‘use‘: 3, ‘games‘: 3, ‘playing‘: 3, ‘our‘: 3, ‘I‘: 3, ‘online‘: 3, ‘computer‘: 3, ‘all‘: 3, ‘phones‘: 2, ‘school‘: 2, ‘students‘: 2, ‘In‘: 2, ‘my‘: 2, ‘opinion‘: 2, ‘As‘: 2, ‘The‘: 2, ‘s‘: 2, ‘help‘: 2, ‘re‘: 2, ‘when‘: 2, ‘how‘: 2, ‘going‘: 2, ‘Internet‘: 2, ‘much‘: 2, ‘learn‘: 2, ‘from‘: 2, ‘It‘: 2, ‘time‘: 2, ‘they‘: 2, ‘do‘: 2, ‘worse‘: 2, ‘t‘: 2, ‘study‘: 2, ‘Nowadays‘: 1, ‘are‘: 1, ‘becoming‘: 1, ‘popular‘: 1, ‘among‘: 1, ‘middle‘: 1, ‘bring‘: 1, ‘know‘: 1, ‘21st‘: 1, ‘century‘: 1, ‘modern‘: 1, ‘age‘: 1, ‘full‘: 1, ‘A‘: 1, ‘one‘: 1, ‘quickest‘: 1, ‘tools‘: 1, ‘exchange‘: 1, ‘fashionable‘: 1, ‘useful‘: 1, ‘invention‘: 1, ‘so‘: 1, ‘ought‘: 1, ‘best‘: 1, ‘Suppose‘: 1, ‘there‘: 1, ‘sudden‘: 1, ‘accident‘: 1, ‘convenient‘: 1, ‘dial‘: 1, ‘immediately‘: 1, ‘There‘: 1, ‘also‘: 1, ‘relax‘: 1, ‘ourselves‘: 1, ‘by‘: 1, ‘them‘: 1, ‘tired‘: 1, ‘studies‘: 1, ‘not‘: 1, ‘wrong‘: 1, ‘follow‘: 1, ‘fashion‘: 1, ‘but‘: 1, ‘most‘: 1, ‘important‘: 1, ‘thing‘: 1, ‘right‘: 1, ‘way‘: 1, ‘Today‘: 1, ‘ll‘: 1, ‘talk‘: 1, ‘about‘: 1, ‘lives‘: 1, ‘interesting‘: 1, ‘enjoyable‘: 1, ‘Many‘: 1, ‘like‘: 1, ‘very‘: 1, ‘because‘: 1, ‘get‘: 1, ‘English‘: 1, ‘read‘: 1, ‘good‘: 1, ‘newspapers‘: 1, ‘magazines‘: 1, ‘clever‘: 1, ‘send‘: 1, ‘e‘: 1, ‘mails‘: 1, ‘friends‘: 1, ‘quickly‘: 1, ‘keep‘: 1, ‘touch‘: 1, ‘with‘: 1, ‘people‘: 1, ‘over‘: 1, ‘world‘: 1, ‘But‘: 1, ‘spend‘: 1, ‘too‘: 1, ‘stay‘: 1, ‘net‘: 1, ‘bars‘: 1, ‘day‘: 1, ‘night‘: 1, ‘result‘: 1, ‘their‘: 1, ‘lessons‘: 1, ‘don‘: 1, ‘well‘: 1, ‘any‘: 1, ‘think‘: 1, ‘mustn‘: 1, ‘go‘: 1, ‘summer‘: 1, ‘or‘: 1, ‘winter‘: 1, ‘holidays‘: 1, ‘‘: 1})
# ****************************************************************************************************
# 出现频率最高的5个单词:
# [(‘the‘, 12), (‘and‘, 10), (‘can‘, 10), (‘to‘, 9), (‘in‘, 8)]
# ****************************************************************************************************
4.2 map 映射函数按规律生成列表或集合?
map 函数接收两个参数,一个函数名,一个可迭代对象,一般传入的一个列表对象,列表中的每个元素都按照传入函数的规则生成一个新的列表。最后的返回值是一个 map 对象。map 对象是一个可迭代对象,可以使用 for 循环取出元素。
# 先看一个列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],以该列表为基础每个数字乘以10
# 生成一个新的列表[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
# 代码如下:
l1 = [i for i in range(10)]
l2 = []
for i in l1:
l2.append(i * 10)
print(l2)
# map函数实现上面的功能,代码变的更简单
l3 = [i for i in range(10)]
def mulTen(n):
return n * 10
l4 = map(mulTen, l3)
print(type(l4))
print(l4)
# [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
# <class ‘map‘>
# <map object at 0x000001F560A7B630>
4.3 filter 过滤函数如何使用?如何过滤奇数偶数平方根数?
- filter() 函数按照函数的规则过滤掉符合的元素,返回过滤后的新对象。
- 函数接收两个参数,第一个为函数,第二个为序列。
- 序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
# 实例1:过滤出列表中的所有奇数
# 定义得到奇数的方法,满足条件的就返回会布尔值True
# filter中满足判断条件为True的就加入到新列表中
def is_odd(n):
return n % 2 == 1
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)
odd = []
for i in newlist:
odd.append(i)
print(odd)
# 实例2:过滤出列表中的所有偶数
def is_even(n):
return n % 2 == 0
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
even = []
for i in newlist:
even.append(i)
print(even)
# 实例3:过滤出1~100中平方根是整数的数:1,4,9......81,100
import math
def is_sqr(x):
return math.sqrt(x) % 1 == 0
newlist = filter(is_sqr, range(1, 101))
l = []
for i in newlist:
l.append(i)
print(l)
# <filter object at 0x000001124675F320>
# [1, 3, 5, 7, 9]
# [1, 3, 5, 7, 9]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
案例中部分代码引用来源:https://www.py.cn/jishu/jichu/14894.html
4.4 sort 和 sorted 排序函数的用法区别?
- sort 函数是用在 list 列表上的方法,sorted 可以对可迭代对象进行排序。
- list 的 sort 方法返回的是对已经存在的列表进行操作,该方法无返回值。
- sorted 方法有返回值,返回值的是一个新的 list 列表
- reverse 参数:指定排序的规则,reverse = True 降序,reverse = False 升序(默认)
# sorted案例
l1 = [‘a‘, ‘d‘, ‘c‘, ‘b‘]
# 按字母升序排列
str2 = sorted(l1, key=str.lower)
print(str2)
# 按字母降序排列
str2 = sorted(l1, key=str.lower, reverse=True)
print(str2)
# [‘a‘, ‘b‘, ‘c‘, ‘d‘]
# [‘d‘, ‘d‘, ‘b‘, ‘a‘]
4.5 enumerate 为元素添加下标索引?
参考代码:
# 索引和内容构成一个tuple类型,然后所有tuple数据生成一个元组列表
# 索引位于元组第一个元素位置,内容位于第二个元素位置
numbers = [‘One‘, ‘Two‘, ‘Three‘, ‘Four‘]
# 默认从0开始添加索引(下标)
print(enumerate(numbers))
print(list(enumerate(numbers)))
for i in enumerate(numbers):
print(i)
# 添加起始下标位置
new_numbers = list(enumerate(numbers, start=100))
print(new_numbers)
# <enumerate object at 0x000002A833B689D8>
# [(0, ‘One‘), (1, ‘Two‘), (2, ‘Three‘), (3, ‘Four‘)]
# (0, ‘One‘)
# (1, ‘Two‘)
# (2, ‘Three‘)
# (3, ‘Four‘)
# [(100, ‘One‘), (101, ‘Two‘), (102, ‘Three‘), (103, ‘Four‘)]
4.6 lambda 匿名函数如何使用?
- lambda表达式用于定义一个匿名函数,一般用于定义一个小型函数
- lambda 是一个单一的参数表达式,内部没有类似 def 函数的语句
# 下面就是一个lambda匿名函数,传入参数,返回值就是表达式的计算结果
func = lambda x: x * x - x
res = func(5)
print(res)
# 20
4.7 type 和 help 函数有什么作用?
- type() 函数实际上是一个类,而不是一个函数。在较早的 Python 中,type 用于创建一个动态类。但是如今 type 函数使用最多的功能,用来查看一个变量属于什么类型。
- help() 函数就是名称一样,它是是一个帮助函数,使用该函数可以查看一个函数有什么功能,该函数有的属性,以及该函数的各种信息。
以上是关于Python基础知识的主要内容,如果未能解决你的问题,请参考以下文章