python基础
一. 计算机核心基础
参考: 计算机核心基础, 计算机核心基详解
二. 编程语言
参考: 编程语言与python介绍
1. 简述解释性型语言和编译型的区别
# 解释型
"""
编译型语言类于同声传译,翻译工具就叫解释器。解释器读取程序源代码,解释一行,交给计算机执行一行。
从三个方面回答: 执行效率,开发效率,跨平台性
解释型执行效率对比编译型较低, 是因为解释型语言的实现中,翻译器并不产生目标机器代码,而是产生易于执行的中间代码。这种中间代码与机器代码是不同的,中间代码的解释是由软件支持的,不能直接使用硬件,软件解释器通常会导致执行效率较低。
开发效率高, 是因为用解释型语言编写的程序是由另一个可以理解中间代码的解释程序执行的,与编译程序不同的是,解释程序的任务是逐一将源程序的语句解释成可执行的机器指令,不需要将源程序翻译成目标代码再执行。解释程序的优点是当语句出现语法错误时,可以立即引起程序员的注意,而程序员在程序开发期间就能进行校正。
具有极强的跨平台性, 是因为代码运行是依赖于解释器,不同平台有对应版本的解释器,所以解释型的跨平台性强.
"""
# 编译型
"""
编译型语言类似于谷歌翻译,翻译工具就叫编译器。(例:C语言编译器GCC). 编译器把程序所有的代码完完整整的编译成计算机能识别的二进制指令,之后操作系统会拿着编译好的二进制指令直接操作硬件。
从三个方面回答: 执行效率,开发效率,跨平台性
编译型执行效率高, 是因为编译是指在应用源程序执行之前,就将程序源代码“翻译”成目标代码(即机器语言),因此其目标程序可以脱离其语言环境独立执行,使用比较方便,执行效率较高。
开发效率慢, 是因为应用程序一旦需要修改,必须先修改源代码,然后重新编译、生成新的目标文件才能执行,而只有目标文件而没有源代码,修改会很不方便。所以开发效率低于解释型.
跨平台性差, 是因为编译型代码是针对某一个平台翻译的,当前平台翻译的结果无法拿到不同的平台使用,针对不同的平台必须重新编译,即跨平台性差.
"""
2. 列举你所知道的python2与python3之间的区别
# 编码
"""
py2:默认编码ascii
py3:默认编码utf-8
"""
# 用户交互
"""
# py2
>>> print("hello", "world")
('hello', 'world')
# py3
>>> print("hello", "world")
hello world
py2:input_raw()
py3:input()
1/2的结果
py2:返回0
py3:返回0.5
"""
# 字符串
"""
py2:unicode类型表示字符串,str类型表示字节. py2要在字符串前面加小u来保证py2得的字符串类型不乱码.
py3: str类型表示字符串, bytes类型表示字节. py中字符串前面帮我们默认加了小u,我们加不加都是一样,并不影响使用。
"""
# 作用域关系
"""
py2中函数用关键字global声明某个变量为全局变量,但是在嵌套函数中,想要给一个变量声明为非局部变量是没法实现的。
py3中,新增了关键字nonlocal,使得非局部变量成为可能
"""
3. 列举你所知道的PEP8 Python编码规范
'''
行长度: 每行不超过80个字符(长的导入模块语句和注释里的URL除外)
缩进: 用4个空格来缩进代码,不要用tab, 也不要tab和空格混用.
空行:顶级定义之间空2行, 方法定义之间空1行.
顶级定义之间空两行, 比如函数或者类定义.
方法定义, 类定义与第一个方法之间, 都应该空一行.
函数或方法中, 某些地方要是你觉得合适, 就空一行.
空格:
1. 各种右括号前不要加空格。
2. 逗号、冒号、分号前不要加空格。
3. 当’='用于指示关键字参数或默认参数值时, 不要在其两侧使用空格.
4. 在二元操作符两边都加上一个空格, 比如赋值(=), 比较(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布尔(and, or, not).
导入格式:
1. 每个导入应该独占一行
Yes: import os
import sys
No: import os, sys
2. 导入总应该放在文件顶部, 位于模块注释和文档字符串之后, 模块全局变量和常量之前. 导入应该按照从最通用到最不通用的顺序分组:
标准库导入
第三方库导入
自定义导入
命名:
1. 命名应该见名知意. 尽量单独使用小写字母‘l’,大写字母‘O’等容易混淆的字母。
2. 常量命名使用全部大写的方式,可以使用下划线。
3. 函数命名使用全部小写的方式,可以使用下划线。
4. 类的命名使用驼峰体.
5. 类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。
6. 类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。
注释:
1. 对函数,类的文档字符串的惯例是使用三重双引号""".
2. 对于复杂的操作, 应该在其操作开始前写上若干行注释
3 .对于不是一目了然的代码, 应在其行尾添加注释.为了提高可读性, 注释应该至少离开代码2个空格.
'''
三. python语法入门
参考: 变量, 基本数据类型, 垃圾回收机制, 用户交互, 基本运算符, 可变不可变类型, 条件, 基本运算符之逻辑运算, 基本运算符之成员运算与身份运算, 流程控制之if判断, 深浅拷贝, 流程控制之while循环, 流程控制之for循环
1. 请用至少两种方式实现m与n值交换m=10,n=5
# 定义中间变量交换
swap = m
m = n
n = swap
# 使用交叉赋值
n, m = m, n
2. 简述python的深浅拷贝?
# 注意: 一下的深浅拷贝都是争对可变容器类型的拷贝, 要知道不可变类型赋值以后就会申请新的内存地址加以存放, 并没有所谓的深浅copy.
"""
不可变类型: int, float, str, tuple, bool
可变类型: list, dict, set
"""
# 浅拷贝
"""
python中浅拷贝的2种表现形式:
对于索引类型: 索引类型[:]
对于可变的容器类型(list,dict.set): 类型.copy()
浅拷贝不区分可变容器类型中的可变不可变类型. 对于可变类型共用一份内存地址, 对于不可变类型在没有修改之前共用一份内存地址.
"""
# 深拷贝
"""
python中深拷贝的1种表现形式:
对于可变的容器类型(list,dict.set):
import copy
copy.deepcopy(类型)
深拷贝对可变容器类型中的可变不可变类型. 对于可变类型创建一份新的内存地址, 对于不可变类型在没有修改之前任然共用一份内存地址.
"""
# 深浅拷贝什么时候使用呢?
"""
使用浅copy:如果你想对容器类型进行修改操作时,想保留原来的数据和修改后的数据,这时只有容器类型的第一层全是不可变类型,这个时候就用浅copy。
使用深copy:如果你想对容器类型进行修改操作时,想保留原来的数据和修改后的数据,且你想让两个列表完完全全独立开,这个时候就用深copy。
"""
3. 什么是python的垃圾回收机制?
"""
1) 什么是垃圾回收机制?
垃圾回收机制简称GC, 是python解释器自带的一种机制, 专门用来回收不可用的变量值所占用的内存空间.
2) 为什么要用垃圾回收机制?
程序的运行过程中会申请大量的内存空间, 而对于一些无用的内存空间如果不及时清理的话会导致内存空间是用殆尽, 进而造成内存溢出, 最终导致程序奔溃. 但是管理内存是一件非常繁琐且复杂的事情, python则提供了垃圾回收机制来帮我们程序从复杂的内存管理中解放出来.
3) 垃圾回收机制的三大算法工作模式:
1) 引用计数: 跟踪回收垃圾
引用计数又分直接应用, 间接引用. 如果'值'引用计数为0, '值'占用的内存地址将会被垃圾回收机制回收.
2) 标记/清除: 解决容器类型的循环引用问题
执行前提: 当应用程序可用内存空间快被耗尽.
标记: 有根之人当活, 无根之人当死. 根指的栈区, 也就是说可以通过栈区间接或者直接可以访问到堆区的对象的数据会被保留. 否则执行清除.
清除: 遍历堆区中所有对象, 将没有标记的对象全部清除.
3) 分代回收: 解决引用计数每次回收内存都需要遍历所有对象的效率问题.
根据存活时间划分扫描频率. 刚来的数据权重最低, 扫描频率最高. 数据存活时间越长权重越高, 扫描频率越低.
"""
4. 求结果: or and
v1 = 1 or 3
v2 = 1 and 3
v3 = 0 and 2 and 1
v4 = 0 and 2 or 1
v5 = 0 and 2 or 1 or 4
v6 = 0 or False and 1
"""
>>> v1 = 1 or 3
>>> v2 = 1 and 3
>>> v3 = 0 and 2 and 1
>>> v4 = 0 and 2 or 1
>>> v5 = 0 and 2 or 1 or 4
>>> v6 = 0 or False and 1
>>> v1, v2, v3, v4, v5, v6
(1, 3, 0, 1, 1, False)
"""
四. 基本数据类型及内置方法
参考: 数字类型及其内置方法, 字符串类型及其内置方法, 列表类型及其内置方法, 元组类型及其内置方法, 字典类型及其内置方法, 集合类型及其内置方法
1. 列举字符串,列表,元组,字典每个常用的五个方法?
# 字符串
"""
需要掌握的操作:
strip, lstrip, rstrip
upper, lower
format
split, rsplit
join
replace
startswith, endswith
isdigit
is系列:
islower, isupper
istitle
isalnum, isalpha
isspace
isidentifier
isdigit, isnumeric, isdecimal
了解的操作:
find, rfind, index, rindex
count
center, ljust, rjust, zfill
expandtabs
capitalize, swapcase, title
"""
# 列表
"""
增: append, insert, expand
删: remove, pop, del
排序: sort
需要掌握的操作: count, index, copy, clear, reverse
"""
# 元组
"""
count, index
"""
# 字典
"""
删: del, pop, popitem
键: keys 值: values 键值对: items
需要掌握的操作:
get, clear, setdefault, update, fromkeys
"""
2. 进制之间的转换
"""
其他进制转十进制: int(x, 进制数)
十进制转其他进制: bin(), oct(), hex()
"""
# 二进制转换成十进制:v = "0b1111011"
v = '0b1111011'
print(int(v, 2))
# 十进制转换成二进制:v = 18
v = 18
print(bin(v))
# 八进制转换成十进制:v = "011"
v = "011"
print(int(v, 8))
# 十进制转换成八进制:v = 30
v = 30
print(oct(v))
# 十六进制转换成十进制:v = "0x12"
v = "0x12"
print(int(v, 16))
# 十进制转换成十六进制:v = 87
v = 87
print(hex(v)) # 0x57
3. 有一个列表[3,4,1,2,5,6,6,5,4,3,3]请写出一个函数,找出该列表中没有重复的数的总和
list1 = [3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3]
# 方法一:
def distinct1(li:list):
tmp_list = []
sum_num = 0
for num in li:
if num not in tmp_list:
tmp_list.append(num)
sum_num += num
return sum_num
print(distinct1(list1)) # 21
# 方法二:
def distinct2(li: list):
return sum(set(li))
print(distinct2(list1)) # 21
五. 字符编码与文件处理
参考: 字符编码, 文件处理
1. ASCII, GBK, unicode, utf-8区别?
# ASCII, GBK, unicode, utf-8字符编码介绍
"""
ASCII:
在计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit),有0和1两种状态,因此,8个二进制位可以组合出256种状态,这被称为字节(byte)。上个世纪60年代,美国制定了一套字符编码,对英文字符与二进制之间做了联系,这被称为ASCII码,一直沿用至今。
ASCII码一共规定了128个字符,比如SPACE是32,A是65,这128个符号只用了一个字节的后面七位,最前面的一位统一规定为0。
gbk:
GBK编码是对GB2312的扩展,完全兼容GB2312。采用双字节编码方案,剔出xx7F码位,共23940个码位,共收录汉字和图形符号21886个,GBK编码方案于1995年12月15日发布。它几乎完美支持汉字,因此经常会遇见GBK与Unicode的转换。
unicode:
世界上有多种编码方法,同一个二进制数字可以被解释称不同的符号。因此,在打开一个文本文件时候,就必须知道它的编码方式,用错误的编码方式打开,就会出现乱码。
Unicode编码,这是一种所有符号的编码。
Unicode显然是一个巨大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如U+0041表示英语的大写字母A,U+4e25表示汉字严。
在Unicode庞大的字符集的优势下,还存在一个问题,比如一个汉字,“严”的Unicode是十六进制4e25,转成二进制足足有15位,也就是,这个符号需要2个字节,表示其他字符还存在3个字节或者更多。计算机怎么区别三个字节表示的是同一个符号而不是分开表示三个呢?如果Unicode统一规定,每个符号用3个字节表示,但是某些字母显然不需要3个,那么就浪费了空间,文本文件大小超出了很多,这显然是不合理的。直到UTF8字符编码出现了。
utf-8:
UTF8的最大特点是,它是一种变长编码,可以使用1-4个字节表示一个符号,根据不同的符号来变化字节长度。
UTF8编码规则只有两条:
1)对于单字节的符号,字节的第一位设为0,后面的7位为这个符号的Unicode码。因此,对于英文字母,UTF8编码和ASCII编码是相同的。
2)对于非单字节(假设字节长度为N)的符号,第一个字节的前N位都设为1,第N+1设为0,后面字节的前两位一律设为10,剩下的没有提及的二进制,全部为这个符号的Unicode码。
1,各个编码之间的二进制,是不能互相识别的,会产生乱码。
2,文件的存储,传输,不能是unicode (只能是utf-8 utf-16 gbk gbk2312 ascii等)
"""
# ASCII, GBK, unicode, utf-8字符编码字符与字节的对应关系
"""
ASCII: 只采用1个字节对应一个英文字符
GBK: 采用1个字节对应一个英文字符,采用2个字节对应一个中文字符。
unicode: 采用2个字节对应一个字符,生僻字采用4个字节、8个字节。(注意:无论是英文还是中文,都是采用2个字符)
utf-8:采用1个字节对应一个英文字符,采用3个字节对应一个中文字符。
"""
# 目前编码使用的硬件范围?
"""
目前内存使用的编码: unicode
unicode兼容万国码,与万国字符都有对应关系。
unicode有2个作用:
1、兼容万国字符
2、兼容万国字符编码表对应关系(unicode妥协于此,也就是它目前存在的主要作用)
目前硬盘中使用的编码:utf-8、GBK、Shift-JIS
内存固定使用unicode,我们可以改变的是存入硬盘采用的格式如下样式:
英文+汉字(文本编辑器) ---》 unicode(内存) ---》GBK(硬盘)
英文+日文(文本编辑器) ---》 unicode(内存) ---》Shift-JIS(硬盘)
万国字符(文本编辑器) ---》 unicode(内存) ---》utf-8(硬盘)
注意: 字符编码之间不可以进行转换。例如:GBK不能转成ASCII,因为这两种字符表的对应关系不一样。但是字符编码之间可以使用unicode作为中间介质,可以进行读写操作。
"""