python近期遇到的一些面試問題(一)


整理一下最近被問到的一些高頻率的面試問題。總結一下方便日后復習鞏固用,同時希望可以幫助一些朋友們。

1.python的基本數據類型

主要核心類型分為兩類
不可變類型:
數字(int float bool complex),字符串(string),元祖(tuple),不可變集合(frozenset)。

可變類型:
列表(list),字典(dict),集合(set)
這里的可變不可變,是指內存中的值是否可以被改變

補充一點,其中不可變集合就是一個無序的不可變的集合,元素也只能是可hash的主要用來做字典的鍵,無序,元素不可重復,且元素只能是不可變類型。其次是元組並不是完全不可變的,如果元素含有list那么是可以添加元組里list的值的,原因就是添加元素的時候list的內存地址不會改變。另外過於字典的鍵值的問題,要求是可hash的所以字典的鍵值類型可以是int,string,tuple,和不可變集合。

2.python中的list去重復

這個就很簡單了,首先轉換成set,set的去重機制會完成去重然后再轉回list即可,例如 去重list ,a=[1,2,3,44,5,6,5]

 new_a=list(set(a))

3.python中的集合操作問題

給定兩個集合a={1,2,4,5},b={2,3,4,1,8},求其補集,差集,並集。
首先我們先來了解set的基本運算有哪些

方法 符號 解釋
a.update(b) a|=b 並集,兩個集合的去重后的合並
a.intersection_update(b) a&=b 交集,兩個集合相同的部分的集合
a.difference_update(b) a-=b 差集a中有,b中沒有的集合
a.symmetric_difference_update(b) a^=b 對稱差分,僅屬於a或者僅屬於b 上面的例子話是{3,5,8}
a.add(b)   加操作,這里會報錯因為set是hash存儲,必須存儲不變的對象,例如字符串、數字、元組等。
a.remove(b)   刪除操作 如果a里不包含b會引發異常
a.discard(b)   刪除操作 如果a里不包含b不會引發異常,返回None
a.pop()   取出一個元素
a.clear()   清空列表
ok,上面的問題就可解決了,用符號&=,|=,-=就可以了

4.list合並

這個問題比較 需要注意的是list元素添加的區別
1.append() 向列表尾部追加一個新元素,列表只占一個索引位,在原有列表上增加
2.extend() 向列表尾部追加一個列表,將列表中的每個元素都追加進來,在原有列表上增加
3.+ 直接用+號看上去與用extend()一樣的效果,但是實際上是生成了一個新的列表存這兩個列表的和,只能用在兩個列表相加上
4.+= 效果與extend()一樣,向原列表追加一個新元素,在原有列表上增加
可以通過id屬性查看內存地址的值,了解其運行狀況。

5.正則表達是匹配url

import re
import requests
url="http://www.cnblogs.com"
s=requests.get(url).text()
ss=s.replace(" ","")
urls=re.findall(r"<a.*?href=.*?<\/a>",ss,re.I)
for i in urls:
print (i)
else:
print ('over')

另外附上幾個網上搜到的驗證Url地址的正則表達式

regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
r'localhost|' #localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)

關於python使用re模塊的第三個參數簡單了解

re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法)
re.M(re.MULTILINE): 多行模式,改變'^'和'$'的行為
re.S(re.DOTALL): 點任意匹配模式,改變'.'的行為

6.filter的使用

filter() 函數用於過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。
該接收兩個參數,第一個為函數,第二個為序列,序列的每個元素作為參數傳遞給函數進行判,然后返回 True 或 False,最后將返回 True 的元素放到新列表中。
以下是 filter() 方法的語法:
filter(function, iterable)

需要強調的是python3中filter返回的是一個filter對象。
下面一個例子是去除列表里面的偶數,其實map和reduce就可以實現這件事了。

def is_odd(n):
return n % 2 == 1
filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
#結果: [1, 5, 9, 15]

7 寫一個實現斐波那契的方法

斐波那契數列的定義
f(0) = 1,f(1) = 1,f(n) = f(n-1) + f(n-2)
最好理解的寫法遞歸時間復雜度最大的。

# 遞歸
def Fibonacci_Recursion_tool(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return Fibonacci_Recursion_tool(n - 1) + Fibonacci_Recursion_tool(n - 2)

一般寫的最多的是這樣

def fib(n):  
x,y=0,1
while(n):
x,y,n=y,x+y,n-1
return x

yield的關鍵字實現

def Fibonacci_Yield_tool(n):
a, b = 0, 1
while n > 0:
yield b
a, b = b, a + b
n -= 1
def Fibonacci_Yield(n):
# return [f for i, f in enumerate(Fibonacci_Yield_tool(n))]
return list(Fibonacci_Yield_tool(n))

尾遞歸

def fib(n):
def fib_iter(n,x,y):
if n==0 : return x
else : return fib_iter(n-1,y,x+y)
return fib_iter(n,0,1)

上述代碼簡化

fib=lambda n,x=0,y=1:x if not n else f(n-1,y,x+y)

下面是效率最高矩陣實現,時間復雜度才logn,僅供參考


Step1: n=2時

Step2:設n=k時,公式成立,則有:

等式兩邊同乘以[1,1;1,0]矩陣可得:


左=右,這正是n=k+1時的形式,即當n=k+1時等式成立。

 

由Step1和Step2可知,該數學公式成立。

由此可以知道該問題轉化為計算右邊矩陣的n-1冪問題.
我們利用分治的算法思想可以考慮如下求解一個數A的冪。

以上內容來自:https://www.cnblogs.com/python27/archive/2011/11/25/2261980.html

python代碼實現

def multi(a,b):
c=[[0,0],[0,0]]
for i in range(2):
for j in range(2):
for k in range(2):
c[i][j]=c[i][j]+a[i][k]*b[k][j]
return c
def matrix(n):
base=[[1,1],[1,0]]
ans=[[1,0],[0,1]]
while n:
if n&1:
ans=multi(ans,base)
base=multi(base,base)
n>>=1
return ans[0][1]
print(matrix(100))

8.列表排序

這里就使用時間復雜度為O(nlogn)的快速排序

def quick_sort(array, left, right):  
if left >= right:
return
low = left
high = right
key = array[low]
while left < right:
while left < right and array[right] > key:
right -= 1
array[left] = array[right]
while left < right and array[left] <= key:
left += 1
array[right] = array[left]
array[right] = key
quick_sort(array, low, left - 1)
quick_sort(array, left + 1, high)

關於8大排序算法的一些比較參考:https://www.cnblogs.com/woider/p/6835466.html

9.切片的使用

切片操作要提供三個參數 [start_index: stop_index: step]
start_index是切片的起始位置
stop_index是切片的結束位置(不包括)
step可以不提供,默認值是1,步長值不能為0,不然會報錯ValueError。
當 step 是正數時,以list[start_index]元素位置開始, step做為步長到list[stop_index]元素位置(不包括)為止,從左向右截取,
start_index和stop_index不論是正數還是負數索引還是混用都可以,但是要保證 list[stop_index]元素的【邏輯】位置
必須在list[start_index]元素的【邏輯】位置右邊,否則取不出元素。

例如,如何獲取一個列表的后兩個元素
a=[1,2,3,4,6,8]
new_a=a[-2:]

當 step 是負數時,以list[start_index]元素位置開始, step做為步長到list[stop_index]元素位置(不包括)為止,從右向左截取,
start_index和stop_index不論是正數還是負數索引還是混用都可以,但是要保證 list[stop_index]元素的【邏輯】位置
必須在list[start_index]元素的【邏輯】位置左邊,否則取不出元素。

alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
alist[-1: -5: -1]

假設list的長度(元素個數)是length, start_index和stop_index在符合虛擬的邏輯位置關系時,
start_index和stop_index的絕對值是可以大於length的。比如下面兩個例子:
alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
alist[-11:11]

該部分內容來自:https://blog.csdn.net/xpresslink/article/details/77727507

10.二分法查找

二分法是一種快速查找的方法,時間復雜度低,邏輯簡單易懂,總的來說就是不斷的除以2除以2… 二分法查找非常快且非常常用,但是唯一要求是要求數組是有序的,關於排序請參考第8條列表排序

代碼實現

#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
def BinarySearch(arr, key):
# 記錄數組的最高位和最低位
min = 0
max = len(arr) - 1
if key in arr:
# 建立一個死循環,直到找到key
while True:
# 得到中位數
# 這里一定要加int,防止列表是偶數的時候出現浮點數據
center = int((min + max) / 2)
# key在數組左邊
if arr[center] > key:
max = center - 1
# key在數組右邊
elif arr[center] < key:
min = center + 1
# key在數組中間
elif arr[center] == key:
print(str(key) + "在數組里面的第" + str(center) + "個位置")
return arr[center]
else:
print("沒有該數字!")
if __name__ == "__main__":
arr = [1, 6, 9, 15, 26, 38, 49, 57, 63, 77, 81, 93]
while True:
key = input("請輸入你要查找的數字:")
if key == " ":
print("謝謝使用!")
break
else:
BinarySearch(arr, int(key))
該部分內容來自:https://www.cnblogs.com/bfyin/p/6404173.html

目前的話就是這些問題,后續會另起文章做補充,喜歡的同學可以點個贊或者轉發到朋友圈,分享給更多的小伙兒伴。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM