python常见面试题
2017-06-05 本文已影响71人
syp_xp
转自http://blog.csdn.net/jerry_1126/article/details/44023949
- pythonic 简洁、灵活、可读性强
#交换两个变量值
a,b = b,a
#去掉list中的重复元素
old_list = [1,1,1,3,4]
new_list = list(set(old_list))
#翻转一个字符串
s = 'abcde'
ss = s[::-1]
#用两个元素之间有对应关系的list构造一个dict
names = ['jianpx', 'yue']
ages = [23, 40]
m = dict(zip(names,ages))
#将数量较多的字符串相连,如何效率较高,为什么
fruits = ['apple', 'banana']
result = ''.join(fruits)
#python字符串效率问题之一就是在连接字符串的时候使用‘+’号,例如 s = ‘s1’ + ‘s2’ + ‘s3’ + ...+’sN’,总共将N个字符串连接起来, 但是使用+号的话,python需要申请N-1次内存空间, 然后进行字符串拷贝。原因是字符串对象PyStringObject在python当中是不可变 对象,所以每当需要合并两个字符串的时候,就要重新申请一个新的内存空间 (大小为两个字符串长度之和)来给这个合并之后的新字符串,然后进行拷贝。 所以用+号效率非常低。建议在连接字符串的时候使用字符串本身的方法 join(list),这个方法能提高效率,原因是它只是申请了一次内存空间, 因为它可以遍历list中的元素计算出总共需要申请的内存空间的大小,一次申请完。
- python调试工具
PyChecker是一个python代码的静态分析工具,它可以帮助查找python代码的bug, 会对代码的复杂度和格式提出警告
Pylint 是另外一个工具可以进行coding standard检查。
- GIL
什么是GIL(Global Interpreter Lock)全局解释器锁? 简单地说就是:
每一个interpreter进程,只能同时仅有一个线程来执行, 获得相关的锁, 存取相关的资源.
那么很容易就会发现,如果一个interpreter进程只能有一个线程来执行,
多线程的并发则成为不可能, 即使这几个线程之间不存在资源的竞争.
从理论上讲,我们要尽可能地使程序更加并行, 能够充分利用多核的功能.
- dict中的items和iteritems
>>> D = {'a':1,'b':2,'c':3,'d':4}
>>> D.items() #一次性取出所有
[('a', 1), ('c', 3), ('b', 2), ('d', 4)]
>>> D.iteritems() #迭代对象,每次取出一个。用for循环遍历出来;
<dictionary-itemiterator object at 0x00000000026243B8>
>>> for i in D.iteritems():
print i,
('a', 1) ('c', 3) ('b', 2) ('d', 4)
>>> for k,v in D.iteritems():
print k,
a c b d
总结:
1.一般iteritems()迭代的办法比items()要快,特别是数据库比较大时。
2.在Python3中一般取消前者函数
- with statements
>>> with open('text.txt') as myfile:
while True:
line = myfile.readline()
if not line:
break
print line,
with语句使用所谓的上下文管理器对代码块进行包装,允许上下文管理器实现一些设置和清理操作。
例如:文件可以作为上下文管理器使用,它们可以关闭自身作为清理的一部分。
NOTE:在PYTHON2.5中,需要使用from __future__ import with_statement进行with语句的导入
- python生成制定长度的斐波那契数列
def fibs(x):
result = [0, 1]
for index in range(x-2):
result.append(result[-2]+result[-1])
return result
if __name__=='__main__':
num = input('Enter one number: ')
print fibs(num)
- python生成随机数
>>> import random
>>> random.random()
0.29495314937268713
>>> random.randint(1,11)
8
>>> random.choice(range(11))
3
- 反序迭代一个序列
如果是一个list, 最快的解决方案是:
list.reverse()
try:
for x in list:
“do something with x”
finally:
list.reverse()
如果不是list, 最通用但是稍慢的解决方案是:
for i in range(len(sequence)-1, -1, -1):
x = sequence[i]
- 如何定义一个函数
def func(arg, *args, **kwagrs): #普通函数
func_body
return
lambda x: x **2 #匿名函数
- <.*?> 和<.*>在正则匹配中的含义
import re
s = ‘<html><head><title>Title</title>’
print(re.match(‘<.*>’, s).group())
会返回一个匹配<html><head><title>Title</title>而不是<html>
而
import re
s = ‘<html><head><title>Title</title>’
print(re.match(‘<.*?>’, s).group())
则会返回<html>
<.*>这种匹配称作贪心匹配 <.*?>称作非贪心匹配
- search与match的区别
>>> import re
>>> re.match(r'python','Programing Python, should be pythonic')
>>> obj1 = re.match(r'python','Programing Python, should be pythonic') #返回None
>>> obj2 = re.search(r'python','Programing Python, should be pythonic') #找到pythonic
>>> obj2.group()
'python'
#re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;
#re.search匹配整个字符串,直到找到一个匹配。
- 中文乱码问题
在Python3中,对中文进行了全面的支持,但在Python2.x中需要进行相关的设置才能使用中文。否则会出现乱码。
Python默认采取的ASCII编码,字母、标点和其他字符只使用一个字节来表示,但对于中文字符来说,一个字节满足不了需求。
为了能在计算机中表示所有的中文字符,中文编码采用两个字节表示。如果中文编码和ASCII混合使用的话,就会导致解码错误,从而才生乱码。
解决办法:
交互式命令中:一般不会出现乱码,无需做处理
py脚本文件中:跨字符集必须做设置,否则乱码
首先在开头一句添加:
# coding = utf-8
# 或
# coding = UTF-8
# 或
# -*- coding: utf-8 -*-
其次需将文件保存为UTF-8的格式!
最后: s.decode('utf-8').encode('gbk')
- lambda函数,本实例实现了求素数
函数使用:
代码块重复,这时候必须考虑到函数,降低程序的冗余度
代码块复杂,这时候必须考虑到函数,降低程序的复杂度
Python有两种函数,一种是def定义,一种是lambda函数()
当程序代码很短,且该函数只使用一次,为了程序的简洁,及节省变量内存占用空间,引入了匿名函数这个概念
>>> nums = range(2,20)
>>> for i in nums:
nums = filter(lambda x:x==i or x % i,nums)
>>> nums
[2, 3, 5, 7, 11, 13, 17, 19]
- list和tuple之间的转换
#From list to Tuple
tuple(a_list)
#From Tuple to List
def to_list(t):
return [i if not isinstance(i,tuple) else to_list(i) for i in t]
- 删除list中的重复元素
>>> L1 = [4,1,3,2,3,5,1]
>>> L2 = []
>>> [L2.append(i) for i in L1 if i not in L2]
>>> print L2
[4, 1, 3, 2, 5]
- python中的类型转换
>>> int('1234') # 将数字型字符串转为整形
1234
>>> float(12) # 将整形或数字字符转为浮点型
12.0
>>> str(98) # 将其他类型转为字符串型
'98'
>>> list('abcd') # 将其他类型转为列表类型
['a', 'b', 'c', 'd']
>>> dict.fromkeys(['name','age']) # 将其他类型转为字典类型
{'age': None, 'name': None}
>>> tuple([1, 2, 3, 4]) # 将其他类型转为元祖类型
(1, 2, 3, 4)
详细类型转换
函数 描述
int(x [,base]) 将x转换为一个整数
long(x [,base] ) 将x转换为一个长整数
float(x) 将x转换到一个浮点数
complex(real [,imag]) 创建一个复数
str(x) 将对象 x 转换为字符串
repr(x) 将对象 x 转换为表达式字符串
eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s) 将序列 s 转换为一个元组
list(s) 将序列 s 转换为一个列表
set(s) 转换为可变集合
dict(d) 创建一个字典。d 必须是一个序列 (key,value)元组。
frozenset(s) 转换为不可变集合
chr(x) 将一个整数转换为一个字符
unichr(x) 将一个整数转换为Unicode字符
ord(x) 将一个字符转换为它的整数值
hex(x) 将一个整数转换为一个十六进制字符串
oct(x) 将一个整数转换为一个八进制字符串
- 获取python对象类型
>>> type([]);type('');type(0);type({});type(0.0);type((1,))
<type 'list'>
<type 'str'>
<type 'int'>
<type 'dict'>
<type 'float'>
<type 'tuple'>
- copy一个对象
切片S[:] # 注不能应用于字典
深浅宝贝 # 能应用于所有序列和字典
浅拷贝D.copy()方法
深拷贝deepcopy(D)方法
- python如何实现内存管理
python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。所有这些都是自动完成,不需要像C一样,人工干预,从而提高了程序员的效率和程序的健壮性。
- range函数的用法
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(0, 9, 2)
[0, 2, 4, 6, 8]
>>> range(99,0,-10)
[99, 89, 79, 69, 59, 49, 39, 29, 19, 9]
相区别的是xrange(),每次只取出一个迭代对象,如果是数据量比较大时,效率较高
在Python3中,没有xrange()函数,其功能放在了range()函数上
- 异常处理的作用
程序中出现异常情况时就需要异常处理。比如当你打开一个不存在的文件时。当你的程序中有
一些无效的语句时,Python会提示你有错误存在。下面是一个拼写错误的例子,print写成了Print
下面是异常最常见的几种角色
错误处理
>>>可以在程序代码中捕捉和相应错误,或者忽略已发生的异常。
>>>如果忽略错误,PYTHON默认的异常处理行为将启动:停止程序,打印错误信息。
>>>如果不想启动这种默认行为,就用try语句来捕捉异常并从异常中恢复。
事件通知
>>>异常也可用于发出有效状态的信号,而不需在程序间传递结果标志位。或者刻意对其进行测试
特殊情况处理
>>>有时,发生了某种很罕见的情况,很难调整代码区处理。通常会在异常处理中处理,从而省去应对特殊情况的代码
终止行为
>>>try/finally语句可确保一定会进行需要的结束运算,无论程序是否有异常
非常规控制流程