python 中常见的面试练习题


人生苦短,我用python!

语言特性

返回文章顶部

1. 谈谈对 python 和其他语言的区别
答:
python 是一门语法简洁优美,功能强大无比,应用领域非常广泛,具有强大的第三方库,它是一门强类型的可移植、可扩展、可嵌入的解释型编程语言,属于动态语言。

拿 C 语言和 Python 比: Python 的第三方类库比较齐全并且使用简洁,很少代码就能实现一些功能,如果用 C 去实现相同的功能可能就比较复杂。但是对于速度来说 Python 的运行速度相较于 C 就比较慢了。所以有利的同时也有弊端,毕竟我们的学习成本降低了。

2. 简述解释型和编译型语言
答:
解释型语言是在运行程序的时候才翻译,每执行一次,要翻译一次,效率较低。编译型就是直接编译成机型可以执行的,只翻译一次,所以效率相对来说较高。

3. python 的解释器种类以及相关特点
答:

  • cpython c 语言开发的,使用最广的解释器
  • IPython 基于 CPython 之上的一个交互式计时器,交互方式增强功能和 CPython 一样
  • pypy 目标时执行效率,采用 JIT 计数。对 python 代码进行动态编译,提高执行效率
  • JPython 运行在 Java 上的解释器,直接把 Python 代码编译成 Java 字节码执行。
  • IronPython 运行在微软 .NET 平台上的解释器,把 python 编译成 .NET 的字节码。

4. python3 和 python2 的区别
答: 这里列举五条

  • print 在 python3 中是函数必须加括号,python2 中 print 为 class。
  • python2 中使用 xrange,python3 使用 range。
  • python2 中默认的字符串类型默认是 ASCII,python3 中默认的字符串类型是 Unicode。
  • python2 中 / (除) 的结果是整型,python3 中是浮点类型。
  • python2 中声明元类:metaclass = MetaClass, python3 中声明元类:class newclass(metaclass = MetaClass): pass。
  • 等等……

5. python3 和 python3 中 int 和long 的区别
答:
python2 有 int 和 long 类型。int 类型最大值不能超过 sys.maxint,而这个最大值是平台相关的。可以通过在数字的末尾附上一个 L 来定义长整型,显然,它比 int 类型表示的数字范围更大。在python3 里,只有一种证书类型 int ,大多数情况下,和 python2 中的长整型类似。

6. xrange 和range 的区别
答:
xrange 是在 python2 中的用法,python3 中只有range xrange 用法与 range 完全相同,所不同的是生成的不是一个 list 对象,而是一个生成器。

编码规范

返回文章顶部

1. 什么是PEP8
答:
PEP8 通常听别人提起,但是具体的指什么内容呢,简单介绍一下《python Enhancement Proposal # 8》(8号 python 增强提案)又叫PEP8,它针对的 python 代码格式而编订的风格指南。

2. 了解python之禅
答:
通过 import this 语句可以获取其具体的内容,它告诉大家如何写出高效整洁的代码。
3. 了解DocStrings
答:
DocStrings 文档字符串是一个重要工具,用于解释文档程序,帮助你的程序文档更加简单易懂,主要是解释代码作用的。

4. 了解类型注解
答:
PEP 484 引入了类型提示,这使得可以对 python 代码进行静态类型检查。在使用 Ide 的时候可以获取到参数的类型,更方便传入参数。使用格式如下:

def foo(num:int) -> None:
    print(f"接收到的数字是:{num}")

介绍下这个简单例子,我们可以在函数的参数部分使用参数名 + :+ 类型,来指定参数可以接受的类型,这里的话就是 num 参数为 int 类型,然后 -> 接的是返回值的类型。这里返回值为 None,然后通过 fstring 格式化字符串输出传入的数字。

5. 列举你知道 python 对象的命名规范,例如方法或者类等
答:
类:总是使用首字母大写单词串,如 MyClass。内部类可以使用额外的前导下划线连接各个单词。方法名类似 常量:常量名所有字母大写 等

6. python 中的注释有几种
**答:**总体来说分为两种,单行注释 、 多行注释

  • 单行注释:重要代码的前面,添加一行解释说明的文字,以符号#开头。
  • 多行注释:使用三个单引号 或者 三个双引号,包括要注释的内容;
    1)文档注释:每个 python 文件的开头,以三对双引号包括起来的注释,用于描述当前文件的作用、作者、时间、版本、……等信息。
    2)多行注释:以三对单引号包括起来的一段注释,用于解释说明一行或者多行代码的作用。

7. 如何优雅的给一个函数加注释
答:
可以使用 docstring 配合类型注解。

8. 如何给变量加注释
答:
可以通过变量名:类型的方式如下:

a: str = "this is string type"

9. python 代码缩进中是否支持Tab键和空格混用。
答:
不允许 Tab 键和空格键混用,这种现象在使用 sublime 的时候尤为明显。
一般推荐使用4个空格代替 Tab 键。

10. 是否可以在依据 import 中导入多个库
答:
可以,但是不推荐;因为一次导入多个模块可读性不是很好,所以一行导入一个模块会比较好,同样的尽量少用 from modulename import*,因为判断某个函数或者属性的来源有些困难,不方便调试,可读性也降低 了。

11. 在给 py 文件命名的时候需要注意什么
答:
给文件命名的时候不要和标准库的一些模块重复,比如 abc。另外名字要有意义,不建议数字开头或者中文命名。

12. 列举几个规范 python 代码风格的工具
答:
pylint 和 flake 8

数据类型-字符串

返回文章顶部

1. 列举 python 中的基本数据类型
答:
python3 中有六个标准的数据类型:字符串(string) 、数字(Digit) 、列表(List) 、元组(Tuple) 、 集合(set) 、 字典(Dictionar);
数字 :整数(int) 、 浮点数(float) 、 复数(complex) 、 布尔类型(bool)

2. 如何区别可变数据类型和不可变数据类型
答: 从对象内存地址方向来说

  • 可变数据类型:在内存地址不变的情况下,值可改变(列表和字典是可变类型,但是字典中的 key(键) 必须是不可变类型)
  • 不可变数据类型:内存改变,值也跟着改变。(数字,字符串,布尔类型,都是不可变类型)可以通过 id() 方法进行内存地址的检测。

3. 将"hello world"转换为首字母大写"Hello World"
答: 题目要求:首字母大写,空格隔开为一个单词;每个单词的首字母大写。

a = "hello word"
print(a.title())    # Hello Word

4. 如何检测字符串中含有数字
答: 可以通过 isdigit() 方法判断字符串是否全部由数字组成,例子如下:

s1 = "123456".isdigit()
print(s1)   # True
s2 = "123456a".isdigit()
print(s2)   # False

5. 将字符串"ilovechina"进行反转
答: 字符串切片 返取

s1 = "ilovechina"
print(s1[::-1]) # anihcevoli

6. python 中的字符串格式化方式你知道哪些
答:
%s ,format, fstring(python3.6 版本开始才支持,现在推荐的写法)

"""
字符串格式化的展示:
%s 占位符      # python 传统语法中使用较多的一种操作。
S.format()     # python 3.4+ 版本出现的一种字符串格式化展示, %s 的升级版。
f-string       # f-string 3.6+ 版本中出现的一种字符串格式化展示,format 的升级版。
"""

# 一、%s 占位符

# %s 占位符
# %s 占据一个位置,使用字符串填充【常用】
# %d 占据一个位置,使用整数填充。
# %f 占据一个位置,使用浮点数填充。
name = "zhangsan"
age = 18
pi = 3.1415926535
s1 = 1
s2 = 12
# 传统语法,语法拼接过程非常繁琐
print("自我介绍:姓名:" + name + ",年龄:" + str(age))    # 自我介绍:姓名:zhangsan,年龄:18

# ① % 占位符的基本语法
print("自我介绍:姓名:%s,年龄:%s" % (name, age))     # 自我介绍:姓名:zhangsan,年龄:18

# ② 占位符-格式化展示:指定宽度和对齐方式
print("姓名:%10s" % name)     # 设置10个宽度,默认右对齐
# 姓名:  zhangsan
print("姓名:%-10s" % name)    # 设置10个宽度,左对齐
# 姓名:zhangsan

# ③ 占位符-格式化展示:指定保留小数点后位数。(默认保留.后6位数,最后一位四舍五入。)
print("输出圆周率:%f" % pi)      # 输出圆周率:3.141593    (默认保留.后6位数,最后一位四舍五入。)
print("输出圆周率:%.2f" % pi)    # 输出圆周率:3.14    (保留小数点后的2位数。)

# ④ 占位符-格式化展示:输出编号时以0补充操作
print("房间号, %03d" % s1)     # 房间号, 001
print("房间号, %03d" % s2)     # 房间号, 012



# 二、format() 格式化方法
name = "lisi"
age = 18
pi = 3.1415926535
# ① format() 基本语法:
print("自我介绍:姓名:{},年龄:{}".format(name,age))
# 自我介绍:姓名:lisi,年龄:18
print("自我介绍:姓名:{b_name},年龄:{a_age}".format(a_age = age,b_name = name))
# 自我介绍:姓名:lisi,年龄:18

# ② format() 格式化:对齐操作{:对齐方式 宽度}
print("姓名:{}".format(name))     # lisi
print("姓名:{:<10}".format(name)) # lisi      |
print("姓名:{:>10}".format(name)) # |      lisi
print("姓名:{:^10}".format(name)) # |   lisi   |
print("姓名:{:^9}".format(name))  # |  lisi   |    (左右不平均时,左少右多、)

# ③ format() 格式化:保留小数操作
print("圆周率:{:f}".format(pi))        # 圆周率:3.141593
print("圆周率:{:.2f}".format(pi))      # 圆周率:3.14



# 三、f-string 格式化字符串
name = "lisi"
age = 18
pi = 3.1415926535
s1 = 1
s2 = 12
# ① f-string 基本语法,字符串中的大括号中的变量,会自动替换数据
print(f"自我介绍:姓名:{name},年龄{age}")        # 自我介绍:姓名:lisi,年龄18

# ② f-string 格式化:宽度和对齐
print(f"姓名:{name}")         # 直接输出
print(f"姓名:{name:10}")      # 占据10个宽度直接输出:默认左对齐。
print(f"姓名:{name:>10}")     # 占据10个宽度直接输出:右对齐。
print(f"姓名:{name:^10}")     # 占据10个宽度直接输出:居中。

# ③ f-string 格式化:保留小数位数
print(f"圆周率:{pi}")          # 直接输出-字符串
# 圆周率:3.1415926535
print(f"圆周率:{pi:f}")        # 直接输出-浮点数
# 圆周率:3.141593
print(f"圆周率:{pi:.2f}")      # 直接输出-保留小数
# 圆周率:3.14

# ④ f-string 格式化:空闲位置以0补充操作
print(f"房间号:{s1:03}")       # 房间号:001
print(f"房间号:{s2:03}")       # 房间号:012

7. 有一个字符串开头和末尾都有空格,比如" adadkjk ",
要求:写一个函数将字符串前后的空格去掉

答: 因为题目要求的是写一个函数,所以我们不能直接使用 strip(),不过我们可以把它封装到函数。

def strip_func(s1):
    return s1.strip()


s1 = "  sakdjfi  "
print(strip_func(s1))   # sakdjfi

8. 获取字符串" 123456 " 最后的两个字符。
答: 使用字符串切片方法,起始值:4,结束值:默认到最后一位,步长:默认为1。代码如下:

s1 = "123456"
print(s1[4:])   # 56

9. 一个编码为 GBK 的字符串 S,要将其转成 UTF-8 编码的字符串格式,应如何操作
答:

s1 = "S".encode("gbk").decode("utf-8", "ignore")
print(s1)

10. (1) s = “info : xiaozhang 33 shandong” 用正则切分字符串实处[‘info’,‘xiaoZhang’,‘33’,‘shangdong’]
(2) a = "你好 中国 ",去除多余空格只留一个空格。

答:
1)我们需要根据冒号或者空格切分

import re
s1 = "info: xiaoZhang 33 shandong"
res = re.split(r": | ", s1)
print(res)  # ['info', 'xiaoZhang', '33', 'shandong']

2)使用join() 方法进行拼接

s1 = "你好 中国"
print("".join(s1.split()))  # 你好中国

11. (1) 怎样将字符串转换为小写。(2) 单引号、双引号、三引号的区别
答:
1)使用字符串的 lower() 方法。

s1 = "ZhAnGSaN"
print(s1.lower())   # zhangsan

2)在 python 中单独使用单引号和双引号是没什么区别的,但是如果引号里面还需要使用印好的时候,就需要注意的是:单引号嵌套的必须是双引号;双引号嵌套的必须是单引号。否则会导致引号冲突。报错;
三引号:同样的三引号㛑分为三单引号和三双引号,两个都可以声明长的字符串的时候使用,如果使用 docstring 就需要使用三双引号。

数据类型 - 列表

返回文章顶部

1. 已知 Alist = [1,2,3,1,2],对 Alist 列表元素去重,写出具体过程
答: 列表和集合之间的转换

s1 = [1,2,3,1,2]
print(list(set(s1)))    # [1, 2, 3]

2. 如何实现"1,2,3" 变成 [“1”, “2”, “3”]
答: split() 方法,按指定(",")的内容进行切割

s1 = "1,2,3"
print(s1.split(","))    # ['1', '2', '3']

3. 给定两个 list,A 和 B ,找出相同元素和不同元素
答:

A = [1,2,5,4,3,1,2,4,5,3,2,1,8]
B = [1,2,5,3,1,24,2,1,5,8,9,2,3]
print("A\B中相同的元素:", set(A) & set(B))  # {1, 2, 3, 5, 8}
print("A\B中不相同的元素:", set(A) ^ set(B))  # {4, 9, 24}

4. [[1,2],[3,4],[5,6]] 一行代码展开改列表,得出[1,2,3,4,5,6]
答:

s1 = [[1,2],[3,4],[5,6]]
x = [j for i in s1 for j in i]
print(x)    # [1, 2, 3, 4, 5, 6]

5. 合并列表[1,5,7,9] 和 [2,2,6,8]
答: 使用extend() 和 + 都可以

s1 = [1,5,7,9]
s2 = [2,4,6,8]
# print(s1 + s2)    # [1, 5, 7, 9, 2, 4, 6, 8]
s1.extend(s2)
print(s1)   # [1, 5, 7, 9, 2, 4, 6, 8]

6. 如何打乱一个列表的元素
答: 随机打乱列表中的元素

import random
s1 = [1,2,3,4,5]
random.shuffle(s1)
print(s1)

数据类型 - 字典

返回文章顶部

1. 字典操作中 del 和 pop 有什么区别
答:
del 可以根据索引值来删除元素的,没有返回值。
pop 可以根据索引弹出一个值,有返回值。

2. 按照字典的内的年龄排序
答:

s1 = [
    {
   "name":"zs", "age":18},
    {
   "name":"ls", "age":28},
    {
   "name":"wl", "age":8}
]
print(sorted(s1, key=lambda x: x["age"]))
# [{'name': 'wl', 'age': 8}, 
# {'name': 'zs', 'age': 18}, 
# {'name': 'ls', 'age': 28}]

3. 请合并下面两个字典 a = {“A” : 1, “B” : 2}, b = {“C” : 3, “D” : 4}
答: 合并字典的方法很多,可以使用 update() 方法 / 字典解包的方式:

a = {
   "A":1, "B":2}
b = {
   "C":3, "D":4}
print({
   **a, **b})   # {'A': 1, 'B': 2, 'C': 3, 'D': 4}
a.update(b)
print(a)    # {'A': 1, 'B': 2, 'C': 3, 'D': 4}

4. 如何使用生成式的方式生成一个字典,写一段功能代码
答:

# 需求:把字典的key 和 value 值调换
s1 = {
   "a":1, "b":2}
print({
   v:k for k, v in s1.items()})

5. 如何把元组 (“a”, “b”) 和元组 (1, 2) , 编程字典{“a” : 1, “b” : 2}
答: zip() 的使用,但是最后记得把 zip 对象再转换为字典

s1 = ("a","b")
s2 = (1,2)
print(dict(zip(s1, s2)))
# {'a': 1, 'b': 2}

数据类型 - 综合

返回文章顶部

1. 下列字典对象键类型不正确的是

A :{1 :0,2:0,3:0}
B :{“a” : 0,“b” : 0, “c” : 0}
C: {(1,2):0, (2,3):0}
D: {[1,2]:0, [2,3]:0}

答: D 因为只有可 hash 的对象才能做字典的键,列表是可变类型不是可 hash 对象,所以不能用列表做为字典的键。

2. 如何交换字典{“A” : 1, “B” : 2} 的键和值
答:

s1 = {
   "A":1, "B":2}
# 方法一:
print({
   value:key for key, value in s1.items()})
print({
   v:k for k, v in s1.items()})
# 方法二:
new_s1 = dict(zip(s1.values(), s1.keys()))
print(new_s1)

3. python 里面如何实现 tuple 和 list 的转换
答:
python 中的类型转换,一般通过类型强转即可完成
tuple 转 list 是 list() 方法、
list 转 tuple 是 tuple() 方法。

4. 我们知道对于列表可以使用切片操作进行部分元素的选择,那么如何对生成器类型的对象事项相同的功能
答: 这个题目考察了 python 标准库的 itertools 模块的掌握情况,该模块提供了操作生成器的一些方法。对于生成器类型我们使用 islice 方法来实现切片的功能。例子如下:

from itertools import islice
gen = iter(range(10))   # 函数用来生成迭代器
# 第一个参数是迭代器,第二个参数是起始索引,第三个参数是结束索引,不支持负数索引
for i in islice(gen,0,4):
    print(i, end=" ")   # 0 1 2 3

5. 请将 [i for i in range(3)] 改成生成器
答: 通过把列表生成式的括号,改为小括号我们就实现了生成器的功能

x = (i for i in range(3))
print(x)

6. a = “hello” 和 b = “你好” 编码成 bytes 类型
答: 这个题目一共有三种方式,第一种是在字符串的前面加一个 b ,第二种可以使用 bytes 方法, 第三种使用字符串 encode 方法。

a = b"hello"
b = bytes("你好","utf-8")
c = "你好".encode("utf-8")
print(a)    # b'hello'
print(b)    # b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(c)    # b'\xe4\xbd\xa0\xe5\xa5\xbd'

7. 下面的代码输出的结果是什么
a = (1,2,3,[4,5,6,7],8)
a[2] = 2

答: 元组里的元素是不能改变的所以这个题目的答案是出现异常;报错。

8. 下面的代码输出的结果是什么
a = (1,2,3,[4,5,6,7],8)
a[3][0] = 2

答: 元组里的元素是不能改变的,这句话严格来说是不准确的,如果元组里面元素本身就是可变类型,比如列表,那么在操作这个元素里的对象时,其内存地址也是不变的。a[3] 对应的元素是列表,然后对列表第一个元素赋值,所以最后的结果是: (1,2,3,[2,5,6,7],8)

操作类题目

返回文章顶部

1. python 交换两个变量的值
答: 在 python 中交换两个对象的值通过下面的方式即可:

a,b = b,a

但是需要强调的是这并不是元组解包,通过 dis 模块可以发现,这是交换操作的字节码是 ROT_TWO ,意思是在栈的顶端做两个值的互换操作。

2. 在读文件操作的时候会使用 read、readline 或者 readlines, 简述他们各自的作用
答:
.read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中;如果希望一行一行的输出那么就可以使用 readline() ,该方法会把文件的内容加载到内存,所以对于大文件的读取操作来说非常消耗内存资源,此时就可以通过 readlines 方法,将文件的句柄生成一个生成器,然后去读就可以了。

3. json 序列化时,可以处理的数据类型有哪些?如何定制支持 datetime 类型?
答:
可以处理的数据类型是 str、int、list、tuple、dict、bool、None,因为 datetime 类不支持 json 序列化,所以我们对他进行拓展。

# 自定义事件序列化
import json
from datetime import datetime, date


# JSONEncoder 不知道怎么去把这个数据转换成json字符串的时候,
# 它就回去调 default()函数,所以都是重写这个函数来处理它本身不支持的数据类型,
# default()函数默认是直接报异常的。
class DateTojson(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        elif isinstance(obj, date):
            return obj.strftime("%Y-%m-%d")
        else:
            return json.JSONEncoder.default(self, obj)


d = {
   "name": "cxa", "data": datetime.now()}
print(json.dumps(d, cls=DateTojson))    # {"name": "cxa", "data": "2020-05-07 15:38:57"}

4. json 序列化时,默认遇到中文会转换成 unicode, 如果想要保留中文怎么办?
答: 可以通过 json.dumps 的 ensure_ascii 参数解决,代码示例如下:

import json
a = json.dumps({
   "name":"张三"}, ensure_ascii=False)
print(a)    # {"name": "张三"}

5. 有两个磁盘文件 A 和 B ,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列), 输出到一个新文件 C 中。
答: 输出的文件 C 的内容为 ABCDEFFGGGST

# 文件A.txt 内容为 ASDCF
# 文件B.txt 内容为 EFGGTG

with open("A.txt") as f1:
    f1_txt = f1.readline()
with open("B.txt") as f2:
    f2_txt = f2.readline()
f3_txt = f1_txt + f2_txt

f3_list = sorted(f3_txt)

with open("C.txt", "a+") as f:
    f.write("".join(f3_list))

6. 如果当前的日期为 20200501,要求写一个函数输出 N 天后的日期,(比如 N 为 2, 则输出 20200503)。
答:
这个大题目考察的是 datetime 里面的 timedelta 方法的使用,参数可选,默认值都为0:datetime.timedelta(days = 0, seconds = 0, microseconds = 0, milliseconds = 0, minutes = 0, hours = 0, weeks = 0) 通过这个参数可以指定不同的日期类型进行加减操作,这里我们需要改的是 days,代码如下

import datetime


def datetime_operate(n: int):
    now = datetime.datetime.now()   # 获取当前时间
    _new_date = now + datetime
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值