Python面试攻略(coding篇)

写在前面

之前为各位小伙伴推出了python面试(嗨谈篇)的内容,主要为各位小伙伴介绍了一些关于python面试中经常出现的概念性问题,那么今天就要从代码入手了,让各位Pythoner在面试的时候遇到这些代码问题也能完全不慌乱,从容解决。

当然,如果你在面试的过程中,正巧遇到了这其中没提及的问题,你认为比较有意思的,也可以在后面的留言板中分享出来让别的小伙伴参考一下看看~

1.台阶问题/斐波那契

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少中跳法:

fib = lambda n: n if n <= 2 else fib(n - 1) + fib(n - 2)

第二种方法:

def memo(func):
   cache = {}
   def wrap(*args):
       if args not in cache:
           cache[args] = func(*args)
       return cache[args]
   return wrap


@memo
def fib(i):
   if i < 2:
       return 1
   return fib(i-1) + fib(i-2)

第三种方法:

def fib(n):
   a, b = 0, 1
   for _ in range(n):
       a, b = b, a + b
   return b

2.去除列表中的重复元素

用集合

list(set(l))

用字典

l1 = ['b','c','d','b','c','a','a']
l2 = {}.fromkeys(l1).keys()
print (l2)

列表推导式

l1 = ['b','c','d','b','c','a','a']
l2 = []
[l2.append(i) for i in l1 if not i in l2]

3.合并两个有序列表

尾递归

def _recursion_merge_sort2(l1, l2, tmp):
   if len(l1) == 0 or len(l2) == 0:
       tmp.extend(l1)
       tmp.extend(l2)
       return tmp
   else:
       if l1[0] < l2[0]:
           tmp.append(l1[0])
           del l1[0]
       else:
           tmp.append(l2[0])
           del l2[0]
       return _recursion_merge_sort2(l1, l2, tmp)

def recursion_merge_sort2(l1, l2):
   return _recursion_merge_sort2(l1, l2, [])

循环算法

思路:

定义一个新的空列表

比较两个列表的首个元素

小的就插入到新列表里

把已经插入新列表的元素从旧列表删除

直到两个旧列表有一个为空

再把旧列表加到新列表后面

def loop_merge_sort(l1, l2):
   tmp = []
   while len(l1) > 0 and len(l2) > 0:
       if l1[0] < l2[0]:
           tmp.append(l1[0])
           del l1[0]
       else:
           tmp.append(l2[0])
           del l2[0]
   tmp.extend(l1)
   tmp.extend(l2)
   return tmp

pop弹出

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

def merge_sortedlist(a,b):
   c = []
   while a and b:
       if a[0] >= b[0]:
           c.append(b.pop(0))
       else:
           c.append(a.pop(0))
   while a:
       c.append(a.pop(0))
   while b:
       c.append(b.pop(0))
   return c
print (merge_sortedlist(a,b))

4.二分查找

#coding:utf-8
def binary_search(list,item):
   low = 0
   high = len(list)-1
   while low<=high:
       mid = int((low+high)/2)
       guess = list[mid]
       if guess>item:
           high = mid-1
       elif guess<item:
           low = mid+1
       else:
           return mid
   return None
mylist = [1,3,5,7,9]
print (binary_search(mylist,3))

参考: http://blog.csdn.net/u013205877/article/details/76411718

5.快排

#coding:utf-8
def quicksort(list):
   if len(list)<2:
       return list
   else:
       midpivot = list[0]
       lessbeforemidpivot = [i for i in list[1:] if i<=midpivot]
       biggerafterpivot = [i for i in list[1:] if i > midpivot]
       finallylist = quicksort(lessbeforemidpivot)+[midpivot]+quicksort(biggerafterpivot)
       return finallylist

print (quicksort([2,4,6,7,1,2,5]))

参考:https://blog.csdn.net/mrlevo520/article/details/77829204

6.使用python实现单例模式

方法一:可以使用__new__方法

在__new__方法中把类实例绑定到类变量_instance上,如果cls._instance为None表示该类还没有实例化过,实例化该类并返回。如果cls_instance不为None表示该类已实例化,直接返回cls_instance

class SingleTon(object):
   def __new__(cls,*args,**kwargs):
       if not hasattr(cls,'_instance'):
           cls._instance = object.__new__(cls,*args,**kwargs)
       return cls._instance
class TestClass(SingleTon):
   a = 1

test1 = TestClass()
test2 = TestClass()
print (test1.a,test2.a)

test1.a=2
print (test1.a,test2.a)
print (id(test1),id(test2))

方法二:使用装饰器,建立过实例的就放到instances里面,下次建立的时候先检查里面有没有

def SingleTon(cls,*args,**kwargs):
   instances = {}
   print (instances)
   def _singleton():
       if cls not in instances:
           instances[cls] = cls(*args,**kwargs)
       print (instances)
       return instances[cls]
   return _singleton

@SingleTon
class LastClass(object):
   a = 1
test1 = LastClass()
print (test1.a)
test2 = LastClass()
print (test2.a)

方法三:使用__metaclass__(元类)关于元类看看这个吧:http://blog.jobbole.com/21351/

class SignalTon(type):
   def __init__(cls,name,bases,dict):
       super(SignalTon, cls).__init__(name,bases,dict)
       cls._instance = None

   def __call__(cls, *args, **kwargs):
       if cls._instance is None:
           cls._instance = super(SignalTon,cls).__call__(*args,**kwargs)
       return cls._instance

class TestClass(object):
   __metaclass__ = SignalTon

test1 = TestClass()
test2 = TestClass()

test1.a = 2
print (test1.a,test2.a)
print (id(test1),id(test2))

方法四:共享属性

所谓单例就是所有的引用(实例,对象)拥有相同的属性和方法,同一个类的实例天生都会有相同的方法,那我们只需要保证同一个类所产生的实例都具有相同的属性。所有实例共享属性最简单直接的方法就是共享__dict__属性指向。

class SingleTon(object):
   _state = {}
   def __new__(cls, *args, **kwargs):
       obj = object.__new__(cls,*args,**kwargs)
       obj.__dict__ = cls._state
       return obj

class TestClass(SingleTon):
   a = 1

test1 = TestClass()
test2 = TestClass()
print (test1.a,test2.a)
test1.a = 2
print (test1.a,test2.a)
print (id(test1),id(test2))

方法五:使用同一个模版,写在mysingleton.py中

class My_Singleton(object):
   def foo(self):
       pass

my_singleton = My_Singleton()

#写在要使用这个实例的py文件里面,在不同的引用的地方都引用相同的实例,以此实现单例模式
from mysingleton import my_singleton
my_singleton.foo()

7.前中后序遍历

深度遍历改变顺序就好了

#coding:utf-8
#二叉树的遍历
#简单的二叉树节点类
class Node(object):
   def __init__(self,value,left,right):
       self.value = value
       self.left = left
       self.right = right

#中序遍历:遍历左子树,访问当前节点,遍历右子树

def mid_travelsal(root):
   if root.left is None:
       mid_travelsal(root.left)
   #访问当前节点
   print(root.value)
   if root.right is not None:
       mid_travelsal(root.right)

#前序遍历:访问当前节点,遍历左子树,遍历右子树

def pre_travelsal(root):
   print (root.value)
   if root.left is not None:
       pre_travelsal(root.left)
   if root.right is not None:
       pre_travelsal(root.right)

#后续遍历:遍历左子树,遍历右子树,访问当前节点

def post_trvelsal(root):
   if root.left is not None:
       post_trvelsal(root.left)
   if root.right is not None:
       post_trvelsal(root.right)
   print (root.value)

8.super函数的原理

#阅读下面的代码,它的输出结果是什么?
class A(object):
 def __init__(self):
  print ("enter A")
  super(A, self).__init__()  # new
  print ("leave A")

class B(object):
 def __init__(self):
  print ("enter B")
  super(B, self).__init__()  # new
  print ("leave B")

class C(A):
 def __init__(self):
  print ("enter C")
  super(C, self).__init__()
  print ("leave C")

class D(A):
 def __init__(self):
  print ("enter D")
  super(D, self).__init__()
  print ("leave D")
class E(B, C):
 def __init__(self):
  print ("enter E")
  super(E, self).__init__()  # change
  print ("leave E")

class F(E, D):
 def __init__(self):
  print ("enter F")
  super(F, self).__init__()  # change
  print ("leave F")

#输出

enter F
enter E
enter B
enter C
enter D
enter A
leave A
leave D
leave C
leave B
leave E
leave F

参考:http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html

参考来源:

https://blog.csdn.net/u013205877/article/details/77542837

https://github.com/taizilongxu/interview_python

如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:大禹编程,您的支持是对我最大的鼓励!共同学习,共同进步:

猜你喜欢

转载自blog.csdn.net/qq_42180849/article/details/82842357