当前位置:   article > 正文

Python面试真实经历(问题及小代码示例)_def name(a): if a==1: return 1 b=a+name(a-1) print

def name(a): if a==1: return 1 b=a+name(a-1) print(f'b:{b}') return b c=name

作者:KotlinPython
原标题:10 家公司 Python 面试题总结
来源:https://mp.weixin.qq.com/s/CaFybiK3fDG19Z61VDo2Aw

本次面试面了10几家,拿了3家offer, 总结下本次面试题汇总,送给有需要的人!

第一家公司问的题目

1 简述解释型和编译型编程语言?

解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候才翻译。这样解释型语言每执行一次就要翻译一次,效率比较低。

用编译型语言写的程序执行之前,需要一个专门的编译过程,通过编译系统,把源高级程序编译成为机器语言文件,翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高,但也不能一概而论,

部分解释型语言的解释器通过在运行时动态优化代码,甚至能够使解释型语言的性能超过编译型语言。

2 Python解释器种类以及特点?

CPython

当 从Python官方网站下载并安装好Python2.7后,就直接获得了一个官方版本的解释器:Cpython,这个解释器是用C语言开发的,所以叫 CPython,在命名行下运行python,就是启动CPython解释器,CPython是使用最广的Python解释器。

IPython

IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的,好比很多国产浏览器虽然外观不同,但内核其实是调用了IE。

PyPy

PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。

Jython

Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。

IronPython

IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

在Python的解释器中,使用广泛的是CPython,对于Python的编译,除了可以采用以上解释器进行编译外,技术高超的开发者还可以按照自己的需求自行编写Python解释器来执行Python代码,十分的方便!

3 位和字节的关系?

bit就是位,也叫比特位,是计算机表示数据最小的单位

byte就是字节

1byte=8bit

1byte就是1B

一个字符=2字节

1KB=1024B

字节就是Byte,也是B

位就是bit也是b

转换关系如下:1)1KB=1024B

1B= 8b

4 请至少列举5个 PEP8 规范(越多越好)。

PEP8 编码规范

a.不要在行尾加分号, 也不要用分号将两条命令放在同一行。

b.每行不超过80个字符(长的导入模块语句和注释里的URL除外)

c.不要使用反斜杠连接行。Python会将圆括号, 中括号和花括号中的行隐式的连接起来

d.宁缺毋滥的使用括号,除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.

e.用4个空格来缩进代码,不要用tab, 也不要tab和空格混用. 对于行连接的情况, 你应该要么垂直对齐换行的元素,或者使用4空格的悬挂式缩进

f.顶级定义之间空2行, 方法定义之间空1行,顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行. 函数或方法中, 某些地方要是你觉得合适, 就空一行.

5 通过代码实现如下转换:

二进制转换成十进制:v = “0b1111011”

#先将其转换为字符串,再使用int函数,指定进制转换为十进制。
print(int("0b1111011",2))
值为123
  • 1
  • 2
  • 3

十进制转换成二进制:v = 18

print("转换为二进制为:", bin(18))
#转换为二进制为: 0b10010
  • 1
  • 2

八进制转换成十进制:v = “011”

print(int("011",8))
#9
  • 1
  • 2

十进制转换成八进制:v = 30

print("转换为八进制为:", oct(30))
#转换为八进制为: 0o36
  • 1
  • 2

十六进制转换成十进制:v = “0x12”

print(int("0x12",16))
#18
  • 1
  • 2

十进制转换成十六进制:v = 87

print("转换为十六进制为:", hex(87))
转换为十六进制为: 0x57
  • 1
  • 2

6 python递归的最大层数?

def fab(n):
if n == 1:
return 1
else:
return fab(n-1)+ n
print (fab(998))
#得到的最大数为998,以后就是报错了,998这个数值莫名想起广告词····
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

import sys
sys.setrecursionlimit(100000)
def foo(n):
   print(n)
   n += 1
   foo(n)
if __name__ == '__main__':
   foo(1)
#得到的最大数字在3922-3929之间浮动,这个是和计算机有关系的,将数字调到足够大了,已经大于系统堆栈,python已经无法支撑到太大的递归崩了。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

7 ascii、unicode、utf-8、gbk 区别?

最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。

但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。

新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。

UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

8 字节码和机器码的区别?

机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。

通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。

用机器语言编写程序,编程人员要首先熟记所用计算机的全部指令代码和代码的涵义。手编程序时,程序员得自己处理每条指令和每一数据的存储分配和输入输出,还得记住编程过程中每步所使用的工作单元处在何种状态。这是一件十分繁琐的工作,编写程序花费的时间往往是实际运行时间的几十倍或几百倍。而且,编出的程序全是些0和1的指令代码,直观性差,还容易出错。现在,除了计算机生产厂家的专业人员外,绝大多数的程序员已经不再去学习机器语言了。

  • 机器语言是微处理器理解和使用的,用于控制它的操作二进制代码。
  • 8086到Pentium的机器语言指令长度可以从1字节到13字节。
  • 尽管机器语言好像是很复杂的,然而它是有规律的。
  • 存在着多至100000种机器语言的指令。这意味着不能把这些种类全部列出来。

总结:机器码是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难编写,一般从业人员接触不到。

字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。

通常情况下它是已经经过编译,但与特定机器码无关。字节码通常不像源码一样可以让人阅读,而是编码后的数值常量、引用、指令等构成的序列。

字节码主要为了实现特定软件运行和软件环境、与硬件环境无关。字节码的实现方式是通过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为可以直接执行的指令。字节码的典型应用为Java bytecode。

字节码在运行时通过JVM(JAVA虚拟机)做一次转换生成机器指令,因此能够更好的跨平台运行。

总结:字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。

9 三元运算规则以及应用场景?

表达式格式
为真时的结果 if 判定条件 else 为假时的结果
  • 1
  • 2

事例
1 if 3>2 else 0

10 用一行代码实现数值交换:

a =1
b =2
a,b=b,a
print(a,b)
  • 1
  • 2
  • 3
  • 4

第二家公司问的题目

1 Python3和Python2中 int 和 long的区别?

Python 2有为非浮点数准备的int和long类型。int类型的最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。在Python 3里,只有一种整数类型int,大多数情况下,它很像Python 2里的长整型。由于已经不存在两种类型的整数,所以就没有必要使用特殊的语法去区别他们。

2 文件操作时:xreadlines和readlines的区别?

read(size)

读入指定大小的内容,以byte为单位,size为读入的字符数,返回str类型

readline()

readline()读取一行内容,放到一个字符串变量,返回str类型。

readlines()

readlines() 读取文件所有内容,按行为单位放到一个列表中,返回list类型。

xreadlines()

返回一个生成器,来循环操作文件的每一行。循环使用时和readlines基本一样,但是直接打印就不同

3列举布尔值为False的常见值?

下面的值在作为布尔表达式的时候,会被解释器看作假(false)

False None 0 "" () [] {}

换句话说,也就是标准值False和None,所有类型的数字0(包括浮点型,长整型和其他类型),空序列(比如空字符串、元组和列表)以及空的字典都为假。其他的一切都被解释为真,包括特殊值True.

也就是说Python中的所有值都能被解释为真值。”标准的“布尔值为True和False。事实上,True和False只不过是1和0的一种“华丽”的说法而已----看起来不同,但是作用相同。

4 lambda表达式格式以及应用场景?

对于简单的函数,也存在一种简便的表示方式,即:lambda表达式

#普通函数
def func(a):
   return a+1
print 'test1_func0:',func(1000)
#lambda表达式 
func0 = lambda a:a+1
print 'test2_func0:',func0(1000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

上面这种方法,都实现了将1000+1的结果打印出来这个功能,但是用下面

lambda存在意义就是对简单函数的简洁表示。

说道lambda,这里再赠送一些可以给lambda加buff小伙伴:

map函数

我们使用map函数将会对列表中的所有元素进行操作。map有两个参数(函数,列表),它会在内部遍历列表中的每一个元素,执行传递过来的函数参数。在输出到新列表中。

li = [11, 22, 33]
new_list = map(lambda a: a + 100, li)
输出:[111, 122, 133]
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

reduce函数

对于序列内所有元素进行累计操作:

lst = [11,22,33]
func2 = reduce(lambda arg1,arg2:arg1+arg2,lst)
print 'func2:',func2
输出:func2: 66
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

filter函数

他可以根据条件对数据进行过滤:

li = [11, 22, 33]
new_list = filter(lambda arg: arg > 22, li)
print new_list
输出:[33]
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

divmod()

函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。

>>>divmod(7, 2)
(3, 1)
>>> divmod(8, 2)
(4, 0)
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

zip() 函数

用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5 arg和kwarg作用*

首先我们可以定一个简单的函数, 函数内部只考虑required_arg这一个形参(位置参数)

def exmaple(required_arg):
   print required_arg
exmaple("Hello, World!")
>> Hello, World!
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

那么,如果我们调用函数式传入了不止一个位置参数会出现什么情况?当然是会报错!

arg和*kwarg 可以帮助我们处理上面这种情况,允许我们在调用函数的时候传入多个实参

def exmaple2(required_arg, *arg, **kwarg):
   if arg:
       print "arg: ", arg
   if kwarg:
       print "kwarg: ", kwarg
exmaple2("Hi", 1, 2, 3, keyword1 = "bar", keyword2 = "foo")
>> arg:  (1, 2, 3)
>> kwarg:  {'keyword2': 'foo', 'keyword1': 'bar'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

从上面的例子可以看到,当我传入了更多实参的时候

  • *arg会把多出来的位置参数转化为tuple
  • **kwarg会把关键字参数转化为dict

6 is和==的区别

在讲is和==这两种运算符区别之前,首先要知道Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。

is和==都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。下面来看看具体区别在哪。

==比较操作符和is同一性运算符区别

==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等,例如下面两个字符串间的比较:

>>> a = 'cheesezh'
>>> b = 'cheesezh'
>>> a == b
True
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。通过对下面几个list间的比较,你就会明白is同一性运算符的工作原理:

>>> x = y = [4,5,6]
>>> z = [4,5,6]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
>>>
>>> print id(x)
>>> print id(y)
>>> print id(z)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

7 简述Python的深浅拷贝以及应用场景?

可变对象-不可变对象

在Python中不可变对象指:一旦创建就不可修改的对象,包括字符串,元祖,数字

在Python中可变对象是指:可以修改的对象,包括:列表、字典

>>> L1 = [2,3,4]      #L1变量指向的是一个可变对象:列表  
>>> L2 = L1           #将L1值赋给L2后,两者共享引用同一个列表对象[1,2,3,4]  
>>> L1[0] = 200       #因为列表可变,改变L1中第一个元素的值  
>>> L1; L2            #改变后,L1,L2同时改变,因为对象本身值变了  
[200, 3, 4]  
[200, 3, 4]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果不想改变列表L2的值,有两种方法:切片 和 copy模块

>>> L1 = [2,3,4]   
>>> L2 = L1  
>>> id(L1);id(L2)     #共享引用一个可变对象  
45811784L  
45811784L  
>>> L2 = L1[:]        #切片操作  
>>> id(L1);id(L2)     #切片后,对象就不一样了  
45811784L  
45806920L  
>>> L1[0] = 200  
>>> L1;L2             #L1发生改变,L2没有变化  
[200, 3, 4]  
[2,   3, 4]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

拷贝

切片技术应用于所有的序列,包括:列表、字符串、元祖

但切片不能应用于字典。对字典只能使用D.copy()方法或D.deepcopy()方法.

深浅拷贝,即可用于序列,也可用于字典

import copy
X = copy.copy(Y)      #浅拷贝:只拷贝顶级的对象,或者说:父级对象
X = copy.deepcopy(Y)  #深拷贝:拷贝所有对象,顶级对象及其嵌套对象。或者说:父级对象及其子对象
  • 1
  • 2
  • 3

如果字典只有顶级对象:

如果字典中嵌套对象:

【结论】

  • 深浅拷贝都是对源对象的复制,占用不同的内存空间
  • 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象
  • 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝
  • 序列对象的切片其实是浅拷贝,即只拷贝顶级的对象

8 Python垃圾回收机制?

import sys sys.getrefcount()查看引用计数
字符串中间有空格!?等会重新创建新的字符串
总结
1. 小整数[-5,257)共用对象,常驻内存,不会被释放。
2. 单个字符共用对象,常驻内存。
3. 单个单词,不可修改,默认开启intern机制,共用对象,引用计数为0,则销毁 。
4. 大整数不共用内存,引用计数为0,销毁 .
5. 数值类型和字符串类型在 Python 中都是不可变的,这意味着你无法修改这个对象的值,每次对变量的修改,实际上是创建一个新的对象 .
Garbage collection(GC垃圾回收)
python采用的是引用计数机制为主,标记-清除和分代收集(隔代回收、分代回收)两种机制为辅的策略

引用计数机制的优点:

1、简单

2、实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。
引用计数机制的缺点:
维护引用计数消耗资源
循环引用,解决不了

gc模块

3.1. 垃圾回收机制
导致引用计数+1的情况
1.对象被创建,例如a = "hello"
2.对象被引用,例如b=a
3.对象被作为参数,传入到一个函数中,例如func(a)
4.对象作为一个元素,存储在容器中,例如list1=[a,a]
1. 常用函数
1、gc.set_debug(flags) 设置gc的debug日志,一般设置为gc.DEBUG_LEAK
2、gc.collect([generation]) 显式进行垃圾回收,可以输入参数,0代表只检查零代的对象,1代表检查零,一代的对象,2代表检查零,一,二代的对象,如果不传参数,执行一个full collection,也就是等于传2。 在python2中返回不可达(unreachable objects)对象的数目
3、gc.get_threshold() 获取的gc模块中自动执行垃圾回收的频率。
4、gc.set_threshold(threshold0[, threshold1[, threshold2]) 设置自动执行垃圾回收的频率。
5、gc.get_count() 获取当前自动执行垃圾回收的计数器,返回一个长度为3的列表
Python的GC模块主要运用了引用计数来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”解决容器对象可能产生的循环引用的问题。通过分代回收以空间换取时间进一步提高垃圾回收的效率。

标记-清除

标记-清除的出现打破了循环引用,也就是它只关注那些可能会产生循环引用的对象
缺点:该机制所带来的额外操作和需要回收的内存块成正比。
一旦这个差异累计超过某个阈值(700,10,10),则Python的收集机制就启动了,并且触发上边所说到的零代算法释放“浮动的垃圾”,并且将剩下的对象移动到一代列表。随着时间的推移,程序所使用的对象逐渐从零代列表移动到一代列表。通过这种方法,你的代码所长期使用的对象,那些你的代码持续访问的活跃对象,会从零代链表转移到一代再转移到二代。通过不同的阈值设置,Python可以在不同的时间间隔处理这些对象。Python处理零代最为频繁,其次是一代然后才是二代。

隔代回收

原理:将系统中的所有内存块根据其存活时间划分为不同的集合,每一个集合就成为一个“代”,垃圾收集的频率随着“代”的存活时间的增大而减小。也就是说,活得越长的对象,就越不可能是垃圾,就应该减少对它的垃圾收集频率。那么如何来衡量这个存活时间:通常是利用几次垃圾收集动作来衡量,如果一个对象经过的垃圾收集次数越多,可以得出:该对象存活时间就越长。
dir(builtins)查看内建属性
getattribute内建属性。属性访问拦截器(方法和属性都可以被拦截),可以返回一个值:以后不要在getattribute方法中调用self.xxxx会引起递归时程序死掉
map函数会根据提供的函数对指定序列做映射返回值是列表
map(function, sequence[, sequence, ...]) -> list
• function:是一个函数
• sequence:是一个或多个序列,取决于function需要几个参数
• 返回值是一个list
filter函数python3返回的是生产器filter函数会对指定序列执行过滤操作
filter(function or None, sequence) -> list, tuple, or string
• function:接受一个参数,返回布尔值True或False
• sequence:序列可以是str,tuple,list
list(filter(lambda x x%2==0,[1,2,3,4,5,6])---->[2,4,6]
sorted函数-排序
sorted(iterable, reverse=False) --> new sorted list
functools模块import functools
partial函数(偏函数)把一个函数的某些参数设置默认值,返回一个新的函数,调用这个新函数会更简单。
wraps函数 使用装饰器时,让外界看被装饰的函数时内容一致。
例如,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)。
functools.wraps(func)

9 求结果:

v = dict.fromkeys(['k1','k2'],[])
v['k1'].append('000')
print(v)
v['k1']=666
print(v)
  • 1
  • 2
  • 3
  • 4
  • 5

{‘k1’: [‘000’], ‘k2’: [‘000’]}
{‘k1’: 666, ‘k2’: [‘000’]}

10 求结果

def num():
   return [lambda x:i*x for i in range(4)]
print([m(2) for m in num()])
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

[6, 6, 6, 6]

以上代码的输出是 [6, 6, 6, 6] (而不是 [0, 2, 4, 6])。

这个的原因是 Python 的闭包的后期绑定导致的 late binding,这意味着在闭包中的变量是在内部函数被调用的时候被查找。所以结果是,当任何 multipliers() 返回的函数被调用,在那时,i 的值是在它被调用时的周围作用域中查找,到那时,无论哪个返回的函数被调用,for 循环都已经完成了,i 最后的值是 3,因此,每个返回的函数 multiplies 的值都是 3。因此一个等于 2 的值被传递进以上代码,它们将返回一个值 6 (比如: 3 x 2)。

(顺便说下,正如在 The Hitchhiker’s Guide to Python 中指出的,这里有一点普遍的误解,是关于 lambda 表达式的一些东西。一个 lambda 表达式创建的函数不是特殊的,和使用一个普通的 def 创建的函数展示的表现是一样的。)

这里有两种方法解决这个问题。

最普遍的解决方案是创建一个闭包,通过使用默认参数立即绑定它的参数。例如:

def num():    
   return [lambda x, i=i : i * x for i in range(4)]
  • 1
  • 2
  • 1
  • 2

另外一个选择是,你可以使用 functools.partial 函数:

from functools import partial
from operator import mul
def num():
   return [partial(mul, i) for i in range(4)]
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

有家公司问的题目

直接让我机试 打印99乘法表!

1 一行代码实现99乘法表*

print ("\n".join("\t".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(1, 10)))
==================================================
1*1=1
2*1=2  2*2=4
3*1=3  3*2=6  3*3=9
4*1=4  4*2=8  4*3=12  4*4=16
5*1=5  5*2=10  5*3=15  5*4=20  5*5=25
6*1=6  6*2=12  6*3=18  6*4=24  6*5=30  6*6=36
7*1=7  7*2=14  7*3=21  7*4=28  7*5=35  7*6=42  7*7=49
8*1=8  8*2=16  8*3=24  8*4=32  8*5=40  8*6=48  8*7=56  8*8=64
9*1=9  9*2=18  9*3=27  9*4=36  9*5=45  9*6=54  9*7=63  9*8=72  9*9=81
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2 列举常见的内置函数?

3 如何安装第三方模块?以及用过哪些第三方模块?

使用软件管理工具(pip,pip2,pip3)

python2和python3都自带了pip,而pip就仿佛有一个仓库,将我们需要安装的第三方模块都收纳其中,使用简单的安装命令即可完成安装。

注意事项:用python3自带的pip或者pip3安装的第三方模块就只能为python3的编译器使用,这对于python2的pip和pip2是同理的。

具体安装方法:直接: pip3 install 模块名

常用第三方模块

Requests.Kenneth Reitz写的最富盛名的http库。每个Python程序员都应该有它。

Scrapy.如果你从事爬虫相关的工作,那么这个库也是必不可少的。用过它之后你就不会再想用别的同类库了。

wxPython.Python的一个GUI(图形用户界面)工具。我主要用它替代tkinter。你一定会爱上它的。

Pillow.它是PIL(Python图形库)的一个友好分支。对于用户比PIL更加友好,对于任何在图形领域工作的人是必备的库。

SQLAlchemy.一个数据库的库。对它的评价褒贬参半。是否使用的决定权在你手里。

BeautifulSoup.我知道它很慢,但这个xml和html的解析库对于新手非常有用。

Twisted.对于网络应用开发者最重要的工具。它有非常优美的api,被很多Python开发大牛使用。

NumPy.我们怎么能缺少这么重要的库?它为Python提供了很多高级的数学方法。

SciPy.既然我们提了NumPy,那就不得不提一下SciPy。这是一个Python的算法和数学工具库,它的功能把很多科学家从Ruby吸引到了Python。

matplotlib.一个绘制数据图的库。对于数据科学家或分析师非常有用。

Pygame.哪个程序员不喜欢玩游戏和写游戏?这个库会让你在开发2D游戏的时候如虎添翼。

Pyglet.3D动画和游戏开发引擎。非常有名的Python版本Minecraft就是用这个引擎做的。

pyQT.Python的GUI工具。这是我在给Python脚本开发用户界面时次于wxPython的选择。

pyGtk.也是Python GUI库。很有名的Bittorrent客户端就是用它做的。

Scapy.用Python写的数据包探测和分析库。

pywin32.一个提供和windows交互的方法和类的Python库。

nltk.自然语言工具包。我知道大多数人不会用它,但它通用性非常高。如果你需要处理字符串的话,它是非常好的库。但它的功能远远不止如此,自己摸索一下吧。

nose.Python的测试框架。被成千上万的Python程序员使用。如果你做测试导向的开发,那么它是必不可少的。

SymPy.SymPy可以做代数评测、差异化、扩展、复数等等。它封装在一个纯Python发行版本里。

IPython.怎么称赞这个工具的功能都不为过。它把Python的提示信息做到了极致。包括完成信息、历史信息、shell功能,以及其他很多很多方面。一定要研究一下它。

4 re的match和search区别?

match()函数只检测RE是不是在string的开始位置匹配,search()会扫描整个string查找匹配;也就是说match()只有在0位置匹配成功的话才有返回,

如果不是开始位置匹配成功的话,match()就返回none。

例如:

print(re.match(‘super’, ‘superstition’).span()) 会返回(0, 5)

而print(re.match(‘super’, ‘insuperable’)) 则返回None

search()会扫描整个字符串并返回第一个成功的匹配

例如:print(re.search(‘super’, ‘superstition’).span())返回(0, 5)

5 什么是正则的贪婪匹配?

如:String str="abcaxc";

Patter p="ab.*c";

贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab.*c)。

非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab.*c)。

编程中如何区分两种模式

默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。

量词:{m,n}:m到n个

*:任意多个

+:一个到多个

?:0或一个

6 求结果

l = [i % 2 for i in range(10)]
print(l)
t = (i % 2 for i in range(10))
print(t)
=============================
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
<generator object <genexpr> at 0x000000000271CB10>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

7 求结果

print(1 or 2)
print(1 and 2)
print(1 < (2==2))
print(1 < 3 == 3)
print(True == 3)
print(True == 1)
=============================
1
2
False
True
False
True
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

8 def func(a,b=[]) 这种写法有什么坑?

def func(a,b=[]):
   b.append(a)
   print(b)
func(1)
func(1)
func(1)
func(1)
=================================
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list,第二次执行还是用第一次执行的时候实例化的地址存储,所以三次执行的结果就是 [1, 1, 1] ,想每次执行只输出[1] ,默认参数应该设置为None。

9 如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?

L = [1,2,3]
NL =list(map(str,L))
print(NL)
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

10 1、2、3、4、5 能组成多少个互不相同且无重复的三位数

for x in range(1,5):
   for y in range(1,5):
       for z in range(1,5):
               if (x!=y) and (y!=z) and (z!=x):
                       print("%d%d%d" % (x, y, z))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
      </div>
    </div>
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/807505
推荐阅读
相关标签
  

闽ICP备14008679号