53 个 Python 面试问题与答案

11.解释filter函数的工作原理

Filter 函数顾名思义,是用来按顺序过滤元素。
每个元素都被传递给一个函数,如果函数返回 True,则在输出序列中返回该元素;如果函数返回 False,则将其丢弃。

def add_three(x):
    if x % 2 == 0:
        return True        
    else:
        return Falseli = [1,2,3,4,5,6,7,8][i for i in filter(add_three, li)]
#=> [2, 4, 6, 8]

注意上面所有不能被 2 整除的元素如何被删除的。

12. Python是按引用调用还是按值调用?

如果你在谷歌上搜索这个问题并阅读前几页,你就要准备好进入语义的迷宫了。你最好只是了解它的工作原理。

不可变对象(如字符串、数字和元组等)是按值调用的。请注意下面的例子,当在函数内部修改时,name 的值在函数外部不会发生变化。name 的值已分配给内存中该函数作用域的新块。

name = 'chr'
def add_chars(s):
   s += 'is'
   print(s)
add_chars(name)    
print(name)
#=> chris
#=> chr

可变对象(如列表等)是通过引用调用的。注意下面的例子中,函数外部定义的列表在函数内部的修改是如何影响到函数外部的。函数中的参数指向内存中存储 li 值的原始块。

li = [1,2]
def add_element(seq):
   seq.append(3)
   print(seq)
add_element(li)    
print(li)
#=> [1, 2, 3]
#=> [1, 2, 3]

13. 如何使用reverse函数反转一个列表?

下面的代码对一个列表调用 reverse() 函数,对其进行修改。该方法没有返回值,但是会对列表的元素进行反向排序。

li = ['a','b','c']
print(li)
li.reverse()
print(li)
#=> ['a', 'b', 'c']
#=> ['c', 'b', 'a']

14. 字符串乘法是如何工作的?

让我们看看将字符串 “cat” 乘以 3 的结果。

'cat' * 3
#=> 'catcatcat'

该字符串将自身连接 3 次。

15. 列表乘法是如何工作的?

我们来看看将列表 [1,2,3] 乘以 2 的结果。

[1,2,3] * 2
#=> [1, 2, 3, 1, 2, 3]

输出的列表包含了重复两次的列表 [1,2,3] 的内容。

16. 类中的“self”指的是什么?

“self”引用类本身的实例。这就是我们赋予方法访问权限并且能够更新方法所属对象的能力。

下面,将 self 传递给__init__(),使我们能够在初始化时设置实例的颜色。

class Shirt:
    def __init__(self, color):
        self.color = color

s = Shirt('yellow')
s.color
#=> 'yellow'

17. 如何在Python中连接列表?

将 2 个列表相加,就是将它们连接在一起。但请注意,数组的工作方式不是这样的。

a = [1,2]
b = [3,4,5]

a + b
#=> [1, 2, 3, 4, 5]

18. 浅拷贝和深拷贝之间有什么区别?

我们将在一个可变对象(列表)的上下文中讨论这个问题,对于不可变的对象,浅拷贝和深拷贝的区别并不重要。
我们将介绍三种情况。

1. 引用原始对象。这将新对象 li2 指向 li1 所指向的内存中的同一位置。因此,我们对 li1 所做的任何更改也会在 li2 中发生。

li1 = [['a'],['b'],['c']]
li2 = li1
li1.append(['d'])
print(li2)
#=> [['a'], ['b'], ['c'], ['d']]

2. 创建原始对象的浅拷贝副本。我们可以使用 list() 构造函数来实现这一点。浅拷贝创建一个新对象,但是用对原始对象的引用填充它。因此,向原始列表li3中添加新对象不会传播到 li4 中,但是修改 li3 中的一个对象将传播到 li4 中。

li3 = [['a'],['b'],['c']]
li4 = list(li3)
li3.append([4])
print(li4)
#=> [['a'], ['b'], ['c']]
li3[0][0] = ['X']
print(li4)
#=> [[['X']], ['b'], ['c']]

3. 创建一个深拷贝副本。这是用 copy.deepcopy() 完成的。现在,这两个对象是完全独立的,并且对其中一个对象所做的更改不会对另外一个对象产生影响。

import copy
li5 = [['a'],['b'],['c']]
li6 = copy.deepcopy(li5)
li5.append([4])
li5[0][0] = ['X']
print(li6)
#=> [['a'], ['b'], ['c']]

19. 列表和数组有什么区别?

注意:Python 的标准库有一个 array(数组)对象,但在这里,我特指常用的 Numpy 数组。

  • 列表存在于 Python 的标准库中。数组由 Numpy 定义。
  • 列表可以在每个索引处填充不同类型的数据。数组需要同构元素。
  • 列表上的算术运算可从列表中添加或删除元素。数组上的算术运算按照线性代数方式工作。
  • 列表还使用更少的内存,并显著具有更多的功能。

20. 如何连接两个数组?

记住,数组不是列表。数组来自 Numpy 和算术函数,例如线性代数。

我们需要使用 Numpy 的连接函数 concatenate() 来实现。

import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
np.concatenate((a,b))
#=> array([1, 2, 3, 4, 5, 6])

21. 你喜欢Python的什么?

Python 可读性很强,并且有一种 Python 方式可以处理几乎所有事情,这意味着它有一种简洁明了的首选方法。
我将 Python 与 Ruby进行对比,Ruby 通常有很多种方法来做某事,但是没有指南说哪种方法是首选。

22. 你最喜欢Python的哪个库?

在处理大量数据时,没有什么比 Pandas(熊猫)更有帮助了,因为 Pandas 让操作和可视化数据变得轻而易举。

23. 举出几个可变和不可变对象的例子?

不可变意味着创建后不能修改状态。例如:int、float、bool、string和tuple。
可变意味着可以在创建后修改状态。例如列表(list)、字典(dict)和集合(set)。

24. 如何将一个数字四舍五入到小数点后三位?

使用 round(value, decimal_places) 函数。

a = 5.12345
round(a,3)
#=> 5.123

25. 如何分割一个列表?

分割语法使用 3 个参数,list[start:stop:step],其中 step 是返回元素的间隔。

a = [0,1,2,3,4,5,6,7,8,9]
print(a[:2])
#=> [0, 1]
print(a[8:])
#=> [8, 9]
print(a[2:8])
#=> [2, 3, 4, 5, 6, 7]
print(a[2:8:2])
#=> [2, 4, 6]

26. 什么是pickling?

Pickling 是 Python 中序列化和反序列化对象的常用方法。
在下面的示例中,我们对一个字典列表进行序列化和反序列化。

import pickle
obj = [
   {'id':1, 'name':'Stuffy'},
   {'id':2, 'name': 'Fluffy'}
]
with open('file.p', 'wb') as f:
   pickle.dump(obj, f)
with open('file.p', 'rb') as f:
   loaded_obj = pickle.load(f)
print(loaded_obj)
#=> [{'id': 1, 'name': 'Stuffy'}, {'id': 2, 'name': 'Fluffy'}]

27. 字典和JSON有什么区别?

Dict 是 Python 的一种数据类型,是经过索引但无序的键和值的集合。
JSON 只是一个遵循指定格式的字符串,用于传输数据。

28. 你在Python中使用了哪些ORM?

ORM(对象关系映射)将数据模型(通常在应用程序中)映射到数据库表,并简化了数据库事务。
SQLAlchemy 通常用于 Flask 的上下文中,而 Django 拥有自己的 ORM。

29. any()和all()如何工作?

Any 接受一个序列,如果序列中的任何元素为 true,则返回 true。
All 只有当序列中的所有元素都为 true 时,才返回 true。

a = [False, False, False]
b = [True, False, False]
c = [True, True, True]
print( any(a) )
print( any(b) )
print( any(c) )
#=> False
#=> True
#=> True
print( all(a) )
print( all(b) )
print( all(c) )
#=> False
#=> False
#=> True

30. 字典和列表的查找速度哪个更快?

在列表中查找一个值需要 O(n)时间,因为需要遍历整个列表,直到找到值为止。
在字典中查找一个值只需要 O(1)时间,因为它是一个哈希表。
如果有很多值,这会造成很大的时间差异,因此通常建议使用字典来提高速度。但字典也有其他限制,比如需要唯一键。

页面: 1 2 3 4 5 6

《53 个 Python 面试问题与答案》有2个想法

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注