上海金台灯-Python爬虫开发工程师

面试题 专栏收录该内容
15 篇文章 0 订阅

1. 什么是lambda函数,它有什么好处?

lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数
- lambda 函数比较轻便, 即用即仍, 很适合需要完成一项功能, 但是此功能只在此一处使用, 连名字都很随意的情况下;
- 匿名函数, 一般用来给 filter, map 这样的函数式编程服务;
- 作为回调函数, 传递给某些应用, 比如消息处理

2. 什么是Python的list and dict comprehensions,写一段代码

list and dict comprehensions 列表推导式和字典推导式
列表推导式:

In [1]: list1 = [x for x in range(10)]

In [2]: list1
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

字典推导式:

d = {key: value for (key, value) in iterable}

3. Python里面如何实现tuple和list的转换?

可以使用内置函数直接转换
list---->tuple tuple(list)
tuple---->list list(tuple)

4. 请写出一段Python代码实现删除一个list里面的重复元素

对列表去重有四种方法,如下代码:

def func1(one_list):  
    ''''' 
    使用集合 
    '''  
    return list(set(one_list))  


def func2(one_list):  
    ''''' 
    使用字典的方式 
    '''  
    return {}.fromkeys(one_list).keys()  


def func3(one_list):  
    ''''' 
    使用列表推导的方式 
    '''  
    temp_list=[]  
    for one in one_list:  
        if one not in temp_list:  
            temp_list.append(one)  
    return temp_list  


def func4(one_list):  
    ''''' 
    使用排序的方法 
    '''  
    result_list=[]  
    temp_list=sorted(one_list)  
    i=0  
    while i<len(temp_list):  
        if temp_list[i] not in result_list:  
            result_list.append(temp_list[i])  
        else:  
            i+=1  
    return result_list  


if __name__ == '__main__':  
    AList=[1,2,3,1,2]  
    print func1(AList)  
    print func2(AList)  
    print func3(AList)  
    print func4(AList)

5. Python里面如何拷贝一个对象?

Python中的赋值、浅拷贝和深拷贝:

5.1 赋值:

在python中, 对象的赋值就是简单的对象引用, 这点和C++不同, 如下所示:

a = [1,2,"hello",['python', 'C++']]
b = a
在上述情况下, a和b是一样的, 他们指向同一片内存, b不过是a的别名, 是引用。
我们可以使用b is a 去判断, 返回True, 表明他们地址相同, 内容相同, 也可以使用id()函数来查看两个列表
的地址是否相同。
赋值操作(包括对象作为参数、 返回值)不会开辟新的内存空间, 它只是复制了对象的引用。
也就是说除了b这个名字之外, 没有其他的内存开销。
修改了a, 也就影响了b;同理, 修改了b, 也就影响了a
5.2 浅拷贝(shallow coopy):
浅拷贝会创建新对象, 其内容是原对象的引用。
浅拷贝有三种形式:切片操作、 工厂函数、 copy模块中的copy函数
比如上述的列表a
切片操作: b = a[:] 或者 b = [x for x in a]
工厂函数: b = list(a)
copy函数: b = copy.copy(a)
浅拷贝产生的列表b不再是列表a了, 使用is判断可以发现他们不是同一个对象, 使用id查看, 他们也不指向
同一片内存空间。 但是当我们使用id(x) for x in a 和 id(x) for x in b来查看a和b中元素的地址时, 可以看到二
者包含的元素的地址是相同的。
在这种情况下, 列表a和b是不同的对象, 修改列表b理论上不会影响到列表a。
但是要注意的是, 浅拷贝之所以称之为浅拷贝, 是它仅仅只拷贝了一层, 在列表a中有一个嵌套的list, 如果
我们修改了它, 情况就不一样了。
比如: a[3].append('java')。 查看列表b, 会发现列表b也发生了变化, 这是因为, 我们修改了嵌套的list, 修
改外层元素, 会修改它的引用, 让它们指向别的位置, 修改嵌套列表中的元素, 列表的地址并未发生变化,
指向的都是用一个位置。
5.3 深拷贝(Deep copy):
深拷贝只有一种形式, copy模块中的deepcopy()函数
深拷贝和浅拷贝对应, 深拷贝拷贝了对象的所有元素, 包括多层嵌套的元素。 因此, 它的时间和空间开销
要高。
同样的对列表a, 如果使用 b = copy.deepcopy(a), 再修改列表b将不会影响到列表a, 即使嵌套的列表具有
更深的层次, 也不会产生任何影响, 因为深拷贝拷贝出来的对象根本就是一个全新的对象, 不再与原来的对
象有任何的关联。
5.4 拷贝的注意点:
  • 对于非容器类型, 如数字、 字符, 以及其他的“原子”类型, 没有拷贝一说, 产生的都是原对象的引用。
  • 如果元组变量值包含原子类型对象, 即使采用了深拷贝, 也只能得到浅拷贝。

6. 写一段使用except的函数

try:
    f = open("a.txt")
    print(f.readline())
except:
    print("文件不存在")

7. Python中pass语句的作用是什么?

pass语句不会执行任何操作 ,一般作为占位符或者创建占位程序

8. 如何知道一个Python对象的类型?

使用Python的内置函数  type(变量) 来查看一个变量的类型

9. 介绍一下Python中renge()函数的用法

Python range()函数可创建一个整数列表,一般在for循环中使用
函数语法:

range(start, stop[, step])

参数说明:
- start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
- stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
- step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)

实例:

In [6]: for x in range(10):
   ...:     print(x)
   ...:     
0
1
2
3
4
5
6
7
8
9

10. 用Python re模块匹配HTML tag的时候,<.*><.*?>有什么区别?

<.*>这种匹配称作贪心匹配 <.*?>称作非贪心匹配
第一种写法是,尽可能多的匹配,就是匹配到的字符串尽量长,第二中写法是尽可能少的匹配,就是匹配到的字符串尽量短。
比如<tag>tag>tag>end,第一个会匹配<tag>tag>tag>,第二个会匹配<tag>,如果要匹配到二个 >,就只能自己写了

11. Python中如何生成随机数?

在python中用于生成随机数的模块是random, 在使用前需要import. 如下例子可以酌情列举:
- random.random(): 生成一个0-1之间的随机浮点数
- random.uniform(a, b): 生成[a,b]之间的浮点数
- random.randint(a, b): 生成[a,b]之间的整数
- random.randrange(a, b, step): 在指定的集合[a,b)中, 以step为基数随机取一个数
- random.choice(sequence): 从特定序列中随机取一个元素, 这里的序列可以是字符串, 列表, 元组等

12. 如何在一个function里面设置一个全局的变量?

如果要给全局变量在一个函数里赋值, 必须使用global语句。 global VarName的表达式会告诉Python, VarName
是一个全局变量, 这样Python就不会在局部命名空间里寻找这个变量了

13. Python程序中文乱码问题怎么解决?

在Python2中默认是不支持中文的,我们可以在py文件的开头,指定编码为utf-8

# coding=utf8

14. 列出Python2和Python3的区别

  • 性能: Py3.0运行 pystone benchmark的速度比Py2.5慢30%。 Guido认为Py3.0有极大的优化空间, 在字符串
    和整型操作上可以取得很好的优化效果
  • 编码: Py3.X源码文件默认使用utf-8编码
  • 语法:
1) 去除了<>, 全部改用!=
2) 去除``, 全部改用repr()
3) 关键词加入aswith, 还有True,False,None
4) 整型除法返回浮点数, 要得到整型结果, 请使用//
5) 加入nonlocal语句。 使用noclocal x可以直接指派外围( 非全局) 变量
6) 去除print语句, 加入print()函数实现相同的功能。 同样的还有 exec语句, 已经改为exec()函数
7) 改变了顺序操作符的行为, 例如x<y, 当x和y类型不匹配时抛出TypeError而不是返回随即的 bool值
8) 输入函数改变了, 删除了raw_input, 用input代替:
2.X:guess = int(raw_input('Enter an integer : ')) # 读取键盘输入的方法
3.X:guess = int(input('Enter an integer : '))
9) 去除元组参数解包。 不能def(a, (b, c)):pass这样定义函数了
10) 新式的8进制字变量, 相应地修改了oct()函数。
11) 增加了 2进制字面量和bin()函数
12) 扩展的可迭代解包。 在Py3.X 里, a, b, *rest = seq和 *rest, a = seq都是合法的, 只要求两点: rest是list
对象和seq是可迭代的。
13) 新的super(), 可以不再给super()传参数,
14) 新的metaclass语法:
class Foo(*bases, **kwds):
pass
15) 支持class decorator。 用法与函数decorator一样:
  • 字符和字符串:
1) 现在字符串只有str一种类型, 但它跟2.x版本的unicode几乎一样。
2) 关于字节串, 请参阅“数据类型”的第2条目

数据类型:

1) Py3.X去除了long类型, 现在只有一种整型——int, 但它的行为就像2.X版本的long
2) 新增了bytes类型, 对应于2.X版本的八位串, 定义一个bytes字面量的方法如下:
str对象和bytes对象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互转化。
3) dict的.keys()、 .items 和.values()方法返回迭代器, 而之前的iterkeys()等函数都被废弃。 
同时去掉的还有 dict.has_key(), 用 in替代它吧

面向对象:

1) 引入抽象基类( Abstraact Base ClassesABCs) 。
2) 容器类和迭代器类被ABCs化。
3) 迭代器的next()方法改名为__next__(), 并增加内置函数next(), 用以调用迭代器的__next__()方法
4) 增加了@abstractmethod@abstractproperty两个 decorator, 编写抽象方法( 属性) 更加方便。

异常:

1) 所以异常都从 BaseException继承, 并删除了StardardError
2) 去除了异常类的序列行为和.message属性
3) 用 raise Exception(args)代替 raise Exception, args语法
4) 捕获异常的语法改变, 引入了as关键字来标识异常实例
5) 异常链, 因为__context__在3.0a1版本中没有实现

模块变动:

1) 移除了cPickle模块, 可以使用pickle模块代替。 最终我们将会有一个透明高效的模块。
2) 移除了imageop模块
3) 移除了 audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2,
rexec, sets, sha, stringold, strop, sunaudiodev, timing和xmllib模块
4) 移除了bsddb模块(单独发布, 可以从http://www.jcea.es/programacion/pybsddb.htm获取)
5) 移除了new模块
6) os.tmpnam()和os.tmpfile()函数被移动到tmpfile模块下
7) tokenize模块现在使用bytes工作。 主要的入口点不再是generate_tokens, 而是 tokenize.tokenize()

其他:

1) xrange() 改名为range(), 要想使用range()获得一个list, 必须显式调用:
>>> list(range(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2) bytes对象不能hash, 也不支持 b.lower()、 b.strip()和b.split()方法, 但对于后两者可以使用 b.strip(b’ \n\t\r \f’)和b.
split(b’ ‘)来达到相同目的
3) zip()map()filter()都返回迭代器。 而apply()callable()coerce()execfile()reduce()和reload ()函数都被去
除了现在可以使用hasattr()来替换 callable(). hasattr()的语法如: hasattr(string, '__name__')
4) string.letters和相关的.lowercase.uppercase被去除, 请改用string.ascii_letters 等
5) 如果x < y的不能比较, 抛出TypeError异常。 2.x版本是返回伪随机布尔值的
6) __getslice__系列成员被废弃。 a[i:j]根据上下文转换为a.__getitem__(slice(I, j))或 __setitem__和 __delitem__调用
7) file类被废弃

15. Python的传参是传值还是传址

Python的参数传递有: 位置参数、 默认参数、 可变参数、 关键字参数
函数的传值到底是值传递还是引用传递, 要分情况:
不可变参数用值传递:
像整数和字符串这样的不可变对象, 是通过拷贝进行传递的, 因为你无论如何都不可能在原处改变不可变对象
可变参数是引用传递的:
比如像列表, 字典这样的对象是通过引用传递、 和C语言里面的用指针传递数组很相似, 可变对象能在函数内部改变。

16. with语句的作用,写一段代码?

with open("a.txt","w") as f:
    f.write("Hello Python")
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值