python程序员面试宝典 陈屹_Python面试宝典之基础篇-10

题目46:按照题目要求写出对应的函数。要求:写一个函数,传入一个有若干个整数的列表,该列表中某个元素出现的次数超过了50%,返回这个元素。

def more_than_half(items):

temp, times = None, 0

for item in items:

if times == 0:

temp = item

times += 1

else:

if item == temp:

times += 1

else:

times -= 1

return temp点评:LeetCode上的题目,在Python面试中出现过,利用元素出现次数超过了50%这一特征,出现和temp相同的元素就将计数值加1,出现和temp不同的元素就将计数值减1。如果计数值为0,说明之前出现的元素已经对最终的结果没有影响,用temp记下当前元素并将计数值置为1。最终,出现次数超过了50%的这个元素一定会被赋值给变量temp。

题目47:按照题目要求写出对应的函数。要求:写一个函数,传入的参数是一个列表(列表中的元素可能也是一个列表),返回该列表最大的嵌套深度。例如:列表[1, 2, 3]的嵌套深度为1,列表[[1], [2, [3]]]的嵌套深度为3。

def list_depth(items):

if isinstance(items, list):

max_depth = 1

for item in items:

max_depth = max(list_depth(item) + 1, max_depth)

return max_depth

return 0点评:看到题目应该能够比较自然的想到使用递归的方式检查列表中的每个元素。

题目48:按照题目要求写出对应的装饰器。要求:有一个通过网络获取数据的函数(可能会因为网络原因出现异常),写一个装饰器让这个函数在出现指定异常时可以重试指定的次数,并在每次重试之前随机延迟一段时间,最长延迟时间可以通过参数进行控制。

方法一:

from functools import wraps

from random import random

from time import sleep

def retry(*, retry_times=3, max_wait_secs=5, errors=(Exception, )):

def decorate(func):

@wraps(func)

def wrapper(*args, **kwargs):

for _ in range(retry_times):

try:

return func(*args, **kwargs)

except errors:

sleep(random() * max_wait_secs)

return None

return wrapper

return decorate

方法二:

from functools import wraps

from random import random

from time import sleep

class Retry(object):

def __init__(self, *, retry_times=3, max_wait_secs=5, errors=(Exception, )):

self.retry_times = retry_times

self.max_wait_secs = max_wait_secs

self.errors = errors

def __call__(self, func):

@wraps(func)

def wrapper(*args, **kwargs):

for _ in range(self.retry_times):

try:

return func(*args, **kwargs)

except self.errors:

sleep(random() * self.max_wait_secs)

return None

return wrapper点评:我们不止一次强调过,装饰器几乎是Python面试必问内容,这个题目比之前的题目稍微复杂一些,它需要的是一个参数化的装饰器。

题目49:写一个函数实现字符串反转,尽可能写出你知道的所有方法。点评:烂大街的题目,基本上算是送人头的题目。

方法一:反向切片

def reverse_string(content):

return content[::-1]

方法二:反转拼接

def reverse_string(content):

return ''.join(reversed(content))

方法三:递归调用

def reverse_string(content):

if len(content) <= 1:

return content

return reverse_string(content[1:]) + content[0]

方法四:双端队列

from collections import deque

def reverse_string(content):

q = deque()

q.extendleft(content)

return ''.join(q)

方法五:反向组装

from io import StringIO

def reverse_string(content):

buffer = StringIO()

for i in range(len(content) - 1, -1, -1):

buffer.write(content[i])

return buffer.getvalue()

方法六:反转拼接

def reverse_string(content):

return ''.join([content[i] for i in range(len(content) - 1, -1, -1)])

方法七:半截交换

def reverse_string(content):

length, content= len(content), list(content)

for i in range(length // 2):

content[i], content[length - 1 - i] = content[length - 1 - i], content[i]

return ''.join(content)

方法八:对位交换

def reverse_string(content):

length, content= len(content), list(content)

for i, j in zip(range(length // 2), range(length - 1, length // 2 - 1, -1)):

content[i], content[j] = content[j], content[i]

return ''.join(content)扩展:这些方法其实都是大同小异的,面试的时候能够给出几种有代表性的就足够了。给大家留一个思考题,上面这些方法,哪些做法的性能较好呢?我们之前提到过剖析代码性能的方法,大家可以用这些方法来检验下你给出的答案是否正确。

题目50:按照题目要求写出对应的函数。要求:列表中有1000000个元素,取值范围是[1000, 10000),设计一个函数找出列表中的重复元素。

def find_dup(items: list):

dups = [0] * 9000

for item in items:

dups[item - 1000] += 1

for idx, val in enumerate(dups):

if val > 1:

yield idx + 1000点评:这道题的解法和计数排序的原理一致,虽然元素的数量非常多,但是取值范围[1000, 10000)并不是很大,只有9000个可能的取值,所以可以用一个能够保存9000个元素的dups列表来记录每个元素出现的次数,dups列表所有元素的初始值都是0,通过对items列表中元素的遍历,当出现某个元素时,将dups列表对应位置的值加1,最后dups列表中值大于1的元素对应的就是items列表中重复出现过的元素。

温馨提示:Python面试宝典会持续更新,从基础到项目实战的内容都会慢慢覆盖到。虽然每天只更新5个题目,但是每道题扩散出的信息量还是比较大的,希望对找工作的小伙伴所有帮助。你的点赞、收藏和评论都是我继续创建的动力,请不要吝惜你的赞美。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值