1:为什么学习Python
公司建议使用Python,然后自己通过百度和向有学过Python的同学了解了Python。Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数据分析这方面。在未来我觉得是往自动化,人工智能这方面发展的,所以学习了Python。
2:通过什么途径学习Python
自学,练项目,到GitHub上面找一些小项目学习。
3:谈谈对Python和其他语言的区别
Python属于解释型语言,当程序运行时,是一行一行的解释,并运行,所以调式代码很方便,开发效率高,还有龟叔给Python定位是任其自由发展、优雅、明确、简单,所以在每个领域都有建树,所有它有着非常强大的第三方库,
特点:
语法简洁优美,功能强大,标准库与第三方库都非常强大,而且应用领域也非常广;可移植性,可扩展性,可嵌入性。
缺点:
运行速度慢。
- 解释型
- Python/php (java、C 编译型)
- 弱类型
- Python (java、C 强类型)
- 动态语言
- Python (java、C 静态型)
(1)与Java相比:在很多方面,Python比java要简单,比如java中所有变量必须声明才能使用,而Python不需要声明,用少量的代码构建出很多功能;(高效的高级数据结构)
(2)与PHP相比:python标准包直接提供了工具,并且相对于PHP代码更易于维护;
(3)Python与C相比:
Python 和 C Python这门语言是由C开发而来
对于使用:Python的类库齐全并且使用简洁,如果要实现同样的功能,Python 10行代码可以解决,C可能就需要100行甚至更多.
对于速度:Python的运行速度相较与C,绝逼是慢了
Python的优势:
1、Python 易于学习;
2、用少量的代码构建出很多功能;(高效的高级数据结构)
3、Python 拥有最成熟的程序包资源库之一;
4、Python完全支持面向对象;
5、Python 是跨平台且开源的;
6、动态类型.
4:简述解释型和编译型编程语言
解释型:就是边解释边执行(Python,php)
编译型:编译后再执行(c、java、c#)
5:Python的解释器种类以及相关特点?
CPython
是官方版本的解释器:CPython。是使用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器。
CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行。
IPython
IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。
PyPy
由Python写的解释器,它的执行速度是最快。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),
绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。
Jython
Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
IronPython
IronPython和Jython类似,只不过IronPython是运行在.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
小结:
Python的解释器很多,但使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性。
6:位和字节的关系
1字节 = 8 位
位(bit),数据存储是以“字节”(Byte)为单位,数据传输是以大多是以“位”(bit,又名“比特”)为单位,一个位就代表一个0或1(即一个二进制),二进制是构成存储器的最小单位,每8个位(bit,简写为b)组成一个字节(Byte,简写为B),字节是最小一级的信息单位。
7:b、B、KB、MB、GB的关系
b --->位(bit)
B --->字节 一个字节等于8位
1B = 8 bit
1kb = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
8:PEP8规范
1、使用4个空格而不是tab键进行缩进。
2、每行长度不能超过80
3、使用空行来间隔函数和类,以及函数内部的大块代码
4、必要时候,在每一行下写注释
5、使用文档注释,写出函数注释
6、在操作符和逗号之后使用空格,但是不要在括号内部使用
7、命名类和函数的时候使用一致的方式,比如使用CamelCase来命名类,使用lower_case_with_underscores来命名函数和方法
8、在类中总是使用self来作为默认
9、尽量不要使用魔法方法
10、默认使用UTF-8,甚至ASCII作为编码方式
11、换行可以使用反斜杠,最好使用圆括号
12、不要在一句import中多个库
空格的使用:
各种右括号前不要加空格
逗号、冒号前不要加空格
函数的左括号前不要加空格。如Func(1)
序列的左括号前不要加空格。如list[2]
操作符左右各加一个空格,不要为了对齐增加空格
函数默认参数使用的赋值符左右省略空格
不要将多句语句写在同一行
if/for/while语句中,即使执行语句只有一句,也必须另起一行
包名小写(不含下划线),函数名小写(可含下划线),常量名大写(可含下划线),类名驼峰写法,类属性小写(可含下划线)。
9:通过代码实现如下转换(进制之间转换)
# 二进制转换成十进制-->int
v = "0b1111011"
b = int(v,2)
print(b) # 123
# 十进制转换成二进制--->bin
v2 = 18
print(bin(int(v2)))
# 0b10010
# 八进制转换成十进制
v3 = "011"
print(int(v3,8))
# 11
# 十进制转换成八进制:---> oct
v4 = 30
print(oct(int(v4)))
# 0o36
# 十六进制转换成十进制:
v5 = "0x12"
print(int(v5,16))
# 18
# 十进制转换成十六进制:---> hex
v6 = 87
print(hex(int(v6)))
# 0x57
10:请编写一个函数实现将IP地址转换成一个整数
请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
def v1(addr):
# 取每个数
id = [int(x) for x in addr.split(".")]
print(id)
return sum(id[i] << [24, 16, 8, 0][i] for i in range(4))
print(v1("127.0.0.1"))
# [127, 0, 0, 1]
# 2130706433
11:python递归的最大层数?998
12:求结果(and or or)
1. 求结果:1 or 3
print(1 or 3) # 1
2. 求结果:1 and 3
print(1 and 3) # 3
3. 求结果:0 and 2 and 1
print(0 and 2 and 1) # 0
4. 求结果:0 and 2 or 1
print(0 and 2 or 1) # 1
5. 求结果:0 and 2 or 1 or 4
print(0 and 2 or 1 or 4) # 1
6. 求结果:0 or Flase and 1
print(0 or False and 1) # Flase
总结:
# x or y 如果 x为真,则值为x, 否则为y
# x and y 如果 x 为真,则值为 y,否则为 x
运算符
1. 求结果:2 & 5(与)
print(2 & 5) # 10 & 101 => 000 => 0
2. 求结果:2 ^ 5即2 | 5(或)
print(2 ^ 5) # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7
13:ascii、unicode、utf-8、gbk 区别
Python2 内容进行编码(默认ascii),而Python3对内容进行编码的默认为unicode。
ascii 最多只能用8位来表示(1个字节),即:2**8 = 256,所以,ASCII码最多只能表示 256 个符号。
unicode 万国码,任何一个字符占2个字节
utf-8 万国码的升级版 一个中文字符占3个字节 英文是1个字节 欧洲的是2个字节
gbk 国内版本 一个中文字符占2个字节 英文是1个字节
gbk 转 utf-8 需通过媒介 unicode
14:字节码和机器码的区别
机器码,学名机器语言指令,有时也被称为原生码,是电脑的CPU可直接解读的数据。
字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
什么是机器码
机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。
通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。
总结:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难编写
什么是字节码
字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。
字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。
总结:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
is == 的区别
#is 比较的是内存地址
#== 比较的是值
#int 具有范围:-5---256
#对于int小数据池
范围:-5----256 创建的相间的数字,都指向同一个内存地址
#对于字符串
1、小数据池 如果有空格,那指向两个内存地址,
2、长度不能超过 20
3、不能用特殊字符
i = 'a'*20
j = 'a'*20
print(i is j) # True
i = "a"*21
j = "a"*21
print(i is j) # False
15:三元运算写法和应用场景?
应用场景:简化if语句
# 关于三元运算
# 结果+ if + 条件 + else + 结果
result='gt' if 1>3 else 'lt'
print(result) # lt
# 理解:如果条件为真,把if前面的值赋值给变量,否则把else后面的值赋值给变量。
lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10)) # 14
可替代:
def foo(x,y):
return x+y
print(foo(4,10)) # 14
16:Python3和Python2的区别?
1:打印时,py2需要可以不需要加括号,py3 需要
python2 :print ('lili') , print 'lili'
python3 : print ('lili')
python3 必须加括号
exec语句被python3废弃,统一使用exec函数。
2:内涵
Python2:1,臃肿,源码的重复量很多。
2,语法不清晰,掺杂着C,php,Java,的一些陋习。
Python3:几乎是重构后的源码,规范,清晰,优雅。
3、输出中文的区别
python2:要输出中文 需加 # -*- encoding:utf-8 -*-
Python3:直接搞
4:input不同
python2 :raw_input
python3 :input 统一使用input函数
5:指定字节
python2在编译安装时,可以通过参数-----enable-unicode=ucs2 或-----enable-unicode=ucs4分别用于指定使用2个字节、4个字节表示一个unicode;
python3无法进行选择,默认使用 ucs4
查看当前python中表示unicode字符串时占用的空间:
impor sys
print(sys.maxunicode)
#如果值是65535,则表示使用usc2标准,即:2个字节表示
#如果值是1114111,则表示使用usc4标准,即:4个字节表示
6:
py2:xrange(返回列表)
range(返回生成器)
py3:range 统一使用range,Python3中range的机制也进行修改并提高了大数据集生成效率。
7:在包的知识点里
包:一群模块文件的集合 + __init__
区别:py2:必须有__init__
py3:不是必须的了
8:不相等操作符"<>"被Python3废弃,统一使用"!="
9:long整数类型被Python3废弃,统一使用int
10:迭代器iterator的next()函数被Python3废弃,统一使用next(iterator)
11:异常StandardError 被Python3废弃,统一使用Exception
12:字典变量的has_key函数被Python废弃,统一使用in关键词
13:file函数被Python3废弃,统一使用open来处理文件,可以通过io.IOBase检查文件类型
17:用一行代码实现数值交换
a = 1
b = 2
a, b = b, a
18:Python3和Python2中int和long区别
在python3里,只有一种整数类型int。大多数情况下,和python2中的长整型类似。
19:xrange和range的区别
都在循环时使用,xrange内存性能更好,xrange用法与range完全相同,range一个生成list对象,xrange是生成器。
要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间。
在Python2中:
range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列
xrange用法与range完全相同,所不同的是生成的不是一个数组,而是一个生成器。
由上面的示例可以知道:要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间,这两个基本上都是在循环的时候用。
在 Python3 中,range() 是像 xrange() 那样实现,xrange()被抛弃。
20:文件操作时:xreadlines和readlines的区别?
readlines 返回一个列表
xreadlines 返回一个生成器
21:列列举布尔值为False的常见值?
0,"",{},[],(),set(),False,负数,不成立的表达式,None,等。
22:字符串、列表、元组、字典每个常用的5个方法?
字符串:
字符串用单引号(')或双引号(")括起来,不可变。
s.strip(c):去除空格或指定的字符c;lstrip/rstrip;
s.zfill(w):右对齐,宽度小于w用0前补;
s.ljust(w,c):左对齐,宽度w,填充符c;rjust()右对齐。
s.join(q):用"s"将序列"q"中的元素串起来;
s.partition(sep):以sep为分隔符,把字符串分割,返回一个元组(包含分割符);
s.split(sep=None, maxsplit=-1):把字符串以sep为分隔符分割,maxsplit为分割次数,返回一个列表(不包含分割符);
s.find(t):返回t的最左位置,未找到,返回-1;
s.index(t):返回t的最左位置,未找到,返回ValueError异常;
s.capitalize():第一个字母变大写;
s.title():每个单词首字母大写;
s.center(width, fillchar=None):字符串内容居中,在给定的字符串长度width中内容居中,两边用提供的字符fillchar填充,fillchar默认为空;
s.count(sub, start=None, end=None):在指定位置start与end之间,计算sub字符的数量;
s.endswith(suffix, start=None, end=None):判断字符串在start与end位置之间是不是以某个子序列suffix结尾,类似方法还可有startwith();
s.replace(old, new, count=None):把字符串中某个子序列old替换成一个新序列new,count是替换数,返回一个新字符串;
s.isdigit():判断是否全是数字;
s.isalpha():判断是否全是字母;
s.isalnum():判断是否包含字母或数字;
s.isspace():判断是否是空字符串;
s[start:stop:step]:切片,截取子字符串。
字典:
1:无序(不能索引) 2:数据关联性强 3:键值对,键值对。唯一一个映射数据类型。
字典的键必须是可哈希的,不可变类型。
在同一个字典中,键(key)必须是唯一的。
列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取
1)clear(self):清除字典中的所有元素。
2)copy(self):复制一份元组,相当于一次浅拷贝。
3)fromkeys(self, iter, value=None):分别以iter中的元素为键,以value为值,创建一个字典。
4)get(self, k, d=None):获取字典中键为k的值,如果字典中不包含k,则给出d值,d默认为None。
5)items(self):遍历字典的一个方法,把字典中每对key和value组成一个元组,并把这些元组放在一个类似列表的dict_items中返回。
6)keys(self):遍历字典键keys的一个方法,返回一个类似列表的dict_keys,与items方法用法相同。
7) values(self):遍历字典值value的一个方法,返回一个类似列表的dict_values,与items方法用法相同。
8)pop(self, k, d=None):弹除并返回字典中键为k的值。
9)popitem(self):从字典中随机取出一组键值,返回一个新的元组。
10)setdefault(self, k, default=None):从字典中获取键为k的值,当存在k时,功能和get基本一致,当字典中不存在k时,在原字典上添加键为k、值为default的项,并返回default值。
11)update(self, E=None, **F):给字典新增元素,没有返回值。用法:dict.update(dict2)。
列表:
索引,切片,加,乘,检查成员。
1、List写在方括号之间,元素用逗号隔开。
2、和字符串一样,list可以被索引和切片。
3、List可以使用+操作符进行拼接。
4、List中的元素是可以改变的。
1)append(self, p_object):在原有列表最后位置上追加新元素到列表,不生成新的列表。
2)clear(self):清空列表里面的元素,不生成新列表。
3)copy(self):复制一份列表,相当于一次浅拷贝。
5)extend(self, iterable):把iterable中的每个元素扩展成列表的元素,iterable可以是字符串、列表、集合、元组、字典。
6)index(self, value, start=None, stop=None):查找列表中value元素索引位置,start与stop参数是查找起始与结束位置,默认为None。
7)insert(self, index, p_object):在列表index索引位置插入元素p_object,当index大于列表包含的元素个数时,在最后位置插入元素。
8)pop(self, index=None):从列表中取出index位置的值,index默认为None,此时弹除并返回列表中最后一个值。
9)remove(self, value):移除列表中第一个出现的value元素,value元素不存在列表中时,则抛出ValueError。
10)reverse(self):反转列表元素的位置。
11)sort(self, key=None, reverse=False):给列表中的元素排序,改变原列表!reverse默认False(升序)。【而sorted()函数是生成副本】。
12)[start:stop:step]:切片,从列表中取出一部分元素生成一个新列表,start与stop默认为None,step表示步长值,默认是一个接着一个切取,
如果为2,则表示进行隔一取一操作。步长值为正时表示从左向右取,如果为负,则表示从右向左取。步长值不能为0。
13)索引[index]:获取索引位置index的值。
元组:
()元组的元素不能修改。
1、与字符串一样,元组的元素不能修改。
2、元组也可以被索引和切片,方法一样。
3、注意构造包含0或1个元素的元组的特殊语法规则。
4、元组也可以使用+操作符进行拼接。
1)count(self, value):统计元组中包含value元素的数量,返回一个int值。
2)index(self, value, start=None, stop=None):索引,查找元组中value元素第一个出现的位置,start与stop参数是查找起始与结束位置,默认为None。
3)[start:stop:step]:切片操作。
Set(集合):
集合(set)是一个无序不重复元素的序列。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
1)add(self, *args, **kwargs):在集合里添加一个元素,不生成新的集合。
2)clear(self, *args, **kwargs):清空集合里面的元素,不生成新的集合。
3)copy(self, *args, **kwargs):浅拷贝集合,返回一个新集合。
4)difference(self, *args, **kwargs):传入一个或多个参数集合对比,返回一个与参数集合不一样元素的集合。
5)discard(self, *args, **kwargs):删除集合中的某个元素,如果这个元素没有在集合中,不做操作。
6)isdisjoint(self, *args, **kwargs):对比两个集合,若空交集则返回True,没有则返回False。
7)issubset(self, *args, **kwargs):判断集合的包含关系,是否是参数集合的子集。
8)pop(self, *args, **kwargs):从集合中随机(因集合无序)弹除并返回一个元素,如果集合为空,则报TypeError错误。
9)remove(self, *args, **kwargs):移除集合中的一个元素,这个元素必须在集合中,如果不在,则报TypeError错误。
10)union(self, *args, **kwargs):两个集合拼接返回一个新集合。
11)update(self, *args, **kwargs):更新集合,添加集合中没有的新元素,不返回新集合。
23:lambda表达式格式以及应用场景?
匿名函数:为了解决那些功能很简单的需求而设计的一句话函数。
函数名 = lambda 参数 :返回值
#参数可以有多个,用逗号隔开
#匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
#返回值和正常的函数一样可以是任意数据类型
lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10)) # 14
可替代:
def foo(x,y):
return x+y
print(foo(4,10)) # 14
24:pass的作用
pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句。
25:*arg和**kwargs作用
*arg 代表位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。
**kwargs 代表的关键字参数,返回的是字典,位置参数一定要放在关键字前面。
26. is和==的区别
a = 'lishi'
str1 = "li"
str2 = "shi"
str3 = str1 + str2
print("a == str3",a == str3)
print("a is str3",a is str3)
print("id(a)",id(a))
print("id(str3)",id(str3))
# a == str3 ,True == ---> 只需要内容相等
# a is str3 ,False is ---> 只需要内存地址相等
# id(a) 38565848
# id(str3) 39110280
is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。
== 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。默认会调用对象的__eq__()方法。
27:谈谈Python的深浅拷贝?以及实现方法和应用场景。
浅拷贝只是增加了一个指针指向一个存在的地址,而深拷贝是增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存。采用浅拷贝的情况,释放内存,会释放同一内存,深拷贝就不会出现释放同一内存的错误。
一层的情况:
import copy
# 浅拷贝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2) # [1, 2, 3, 4] [1, 2, 3]
# 深拷贝
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, li2) # [1, 2, 3, 4] [1, 2, 3]
多层的情况:
import copy
# 浅拷贝 指向共有的地址
li1 = [1, 2, 3,[4,5],6]
li2 = li1.copy()
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]
# 深拷贝 重指向
li1 = [1, 2, 3,[4,5],6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]
28:Python垃圾回收机制?
引用计数
标记清除
分代回收
29:Python的可变类型和不可变类型?
可变数据类型:列表、字典、集合
不可变数据类型:数字、字符串、元组