python爬蟲常見面試題(一)

来源:https://www.cnblogs.com/tianyiliang/archive/2019/01/03/10212951.html
-Advertisement-
Play Games

前言 之所以在這裡寫下python爬蟲常見面試題及解答,一是用作筆記,方便日後回憶;二是給自己一個和大家交流的機會,互相學習、進步,希望不正之處大家能給予指正;三是我也是互聯網寒潮下崗的那批人之一,為了找工作而做準備。 一、題目部分 a=['apple', 'banana', 'apple', 't ...


前言

  之所以在這裡寫下python爬蟲常見面試題及解答,一是用作筆記,方便日後回憶;二是給自己一個和大家交流的機會,互相學習、進步,希望不正之處大家能給予指正;三是我也是互聯網寒潮下崗的那批人之一,為了找工作而做準備。

一、題目部分

1、python中常用的數據結構有哪些?請簡要介紹一下。
2、簡要描述python中單引號、雙引號、三引號的區別。
3、如何在一個function里設置一個全局的變數。
4、python裡面如何拷貝一個對象?(賦值、淺拷貝、深拷貝的區別)
5、如果custname字元串的編碼格式為uft-8,如何將custname的內容轉化為gb18030的字元串?
6、請寫出一段python代碼實現刪除list中的重覆元素。
7、這兩個參數是什麼意思?args和 kwargs。
8、
(1)統計如下list單詞及其出現的次數。

a=['apple', 'banana', 'apple', 'tomato', 'orange', 'apple', 'banana', 'watermeton']

(2)給列表中的字典排序:例如有如下list對象:

alist=[{"name":"a", "age":20}, {"name":"b", "age":30}, {"name":"c", "age":25}] 將alist中的元素按照age從小到大排序。

(3)寫出下列代碼的運行結果
1 a = 1
2 def fun(a):
3     a = 2
4 fun(a)
5 print(a)
1 a = []
2 def fun(a):
3     a.append(1)
4 fun(a)
5 print(a)
1 class Person:
2     name = 'Lily'
3  
4 p1 = Person()
5 p2 = Person()
6 p1.name = 'Bob'
7 print(p1.name)
8 print(p2.name)
9 print(Person.name)

二、解答部分

註:以下答案,均為google後結合自己學所知識回答,可能會有不正確的地方,錯誤之處希望大家幫我指正出來,謝謝。

1、python中常用的數據結構有哪些?請簡要介紹一下。

python中常見的數據結構有:列表(list),字典(dict),元組(tuple),字元串(string),集合(set),數字(int或long或float。。。)等。

其中,列表,元祖和字元串可以統一歸為序列類,即這三種數據結構中的元素是有序的。比如,他們都有索引(下標)操作,還有切片、相加和長度(len),最大值(max),最小值(min)操作。這是他們的共同點。

補充:python中常見的數據結構可以統稱為容器(container)。序列(如列表和元組)、映射(如字典)以及集合(set)是三類主要的容器。

另外,關於這個問題,面試官很容易引出另一個問題:python中的哪些數據類型是可變的,哪些是不可變的?

首先,可變/不可變是針對該對象所指向的記憶體中的值是否可變來判斷的。如可變類型的數據類型有列表和字典,還有集合(感謝@自由早晚亂餘生糾正)。不可變類型的數據類型有字元串,元組,數字。

就舉個最簡單的數字的例子,python中有小整數池的概念,即[-5,256]範圍內的整數,python解釋器對他們做了特殊處理,都放在記憶體中的固定位置,不會因為你的操作二發生變化。

現在:a = 1 ,然後我們又重新對a賦值,a = 2,在重新賦值的過程中,整數1所對應的記憶體地址沒有和數字的大小都沒有發生變化,還在記憶體中的固定位置。整數2也是如此。變化的是a的指針(這裡引用C中的概念)從指向數字1變成數字2。a對象指向的記憶體中的值沒有發生變化,因此數字是不可變類型的數據類型。字元串,集合也是同理。

2、簡要描述python中單引號、雙引號、三引號的區別。

 首先,單引號和雙引號在使用時基本上沒有什麼區別,唯一需要註意的是:當字元串中有單引號時,最好在外面使用雙引號;當有雙引號時,最好在外面使用單引號。

三引號一般不常用,除了用來做註釋之外,還可以用來列印多行字元串。特殊用途,是可以列印多行字元串。

1 print('''i
2 love
3 you''') #特殊功能,可以直接列印多行內容,而前面兩種情況需要顯示輸入\n才能換行

輸出結果:

1 i
2 love
3 you

而單引號和雙引號如果想要實現上面的效果,需要加上換行符。

1 print('i\nlove\nyou')
3、如何在一個function里設置一個全局的變數。

先說概念,全局變數是指定義在函數外部的變數。全局變數的作用域為全局。

局部變數是指定義在函數內部的變數。局部變數的作用域為函數內,除了函數就無效了。

這裡舉個例子,如果把函數比作國家,那麼全局就是全球,全局變數好比是阿拉伯數字,每個國家都認識。

所以,根據定義可以知道,在函數內部是無法定義一個全局變數的,只能做到修改已經定義的全局變數。

4、python裡面如何拷貝一個對象?(賦值、淺拷貝、深拷貝的區別)

在python中如何拷貝一個對象是需要根據具體的需求來定的。

(1)賦值:其實就是對象的引用。相當於C的指針,修改了其中一個對象,另一個跟著改變。註意對於不可變對象而言,如果修改了其中一個對象,就相當於修改它的指針指向,另一個對象是不會跟著變化的。

1 a = ['1', '2'] # a是一個可變對象
2 b = a
3 a = a.pop()
4 print(b) # 修改了a,b也跟著變

輸出結果:

1 ['1']

當a為不可變對象時:

1 a = 1
2 b = a
3 a = 2
4 print('b = {}'.format(b))

輸出結果:

1 b = 1

 

(2)淺拷貝:拷貝父對象,但是不會拷貝父對象的子對象。(具體的方法有:b = copy.copy(a),切片如b = a[1:4])

1 a = {1: [1, 2, 3]}
2 b = a.copy()
3 print(a, b)
4 a[1].append(4)
5 print(a, b)

輸出結果為:

{1: [1, 2, 3]} {1: [1, 2, 3]}
{1: [1, 2, 3, 4]} {1: [1, 2, 3, 4]}

當a為不可變對象時:

1 import copy
2 a = 'TEST_STRING'
3 b = copy.copy(a)
4 print(a, b)
5 a = a.lower()
6 print(a, b)

輸出結果:

1 TEST_STRING TEST_STRING
2 test_string TEST_STRING

 (3)深拷貝:完全拷貝了父對象和子對象(具體的方法有:b = copy.deepcopy(a))

1 import copy
2 a = {1: [1, 2, 3]}
3 b = copy.deepcopy(a)
4 print(a, b)
5 a[1].append(4)
6 print(a, b)

輸出結果:

1 {1: [1, 2, 3]} {1: [1, 2, 3]}
2 {1: [1, 2, 3, 4]} {1: [1, 2, 3]}

當a為不可變對象時:

1 import copy
2 a = 'TEST_STRING'
3 b = copy.deepcopy(a)
4 print(a, b)
5 a = a.lower()
6 print(a, b)

輸出結果:

1 TEST_STRING TEST_STRING
2 test_string TEST_STRING

下麵是圖解:

1、b = a: 賦值引用,a 和 b 都指向同一個對象。

2、b = a.copy(): 淺拷貝, a 和 b 是一個獨立的對象,但他們的子對象還是指向統一對象(是引用)。

3、b = copy.deepcopy(a): 深度拷貝, a 和 b 完全拷貝了父對象及其子對象,兩者是完全獨立的。

總結:

(1)當對象為不可變類型時,不論是賦值,淺拷貝還是深拷貝,那麼改變其中一個值時,另一個都是不會跟著變化的。

(2)當對象為可變對象時,如果是賦值和淺拷貝,那麼改變其中任意一個值,那麼另一個會跟著發生變化的;如果是深拷貝,是不會跟著發生改變的。

啊,這一題答案真的是好長啊,累到掉渣!歇會兒。。。

5、如果custname字元串的編碼格式為uft-8,如何將custname的內容轉化為gb18030的字元串?

先將custname編碼格式轉換為unicode,在轉換為gb18030。即custname.decode('utf-8').encode('gb18030')。

註意:unicode編碼是一種二進位編碼,是轉換編碼的中間橋梁。比如需要將utf-8轉換為gbk,那麼就需要先轉換為unicode(decode),再轉為gbk(encode)。

6、請寫出一段python代碼實現刪除list中的重覆元素。

兩種方法:

(1)利用字典的fromkeys來自動過濾重覆值

(2)利用集合set的特性,元素是非重覆的

方法一:

1 a = [1, 2, 3, 4, 5, 2, 3]
2 
3 def fun1(a):
4     a = list(set(a))
5     print(a)
6 
7 fun1(a)

方法二:

1 a = [1, 2, 3, 4, 5, 2, 3]
2 
3 def fun1(a):
4     b = {}
5     b = b.fromkeys(a)
6     c = list(b.keys())
7     print(c)
8 
9 c = fun1(a)
7、這兩個參數是什麼意思?args和 kwargs。

首先,我想說的是*args和**kwargs並不是必須這樣寫,只有前面的*和**才是必須的。你可以寫成*var和**vars。而寫成*args和**kwargs只是約定俗稱的一個命名規定。

*args和**kwargs主要用於函數定義,你可以將不定量的參數傳遞給一個函數。其中,*args 是用來發送一個非鍵值對的可變數量的參數列表給一個函數;**kwargs 允許你將不定長度的鍵值對, 作為參數傳遞給一個函數。 如果你想要在一個函數里處理帶名字的參數, 你應該使用**kwargs

1 def import_args(test, *args):
2     print('param1', test)
3     for item in args:
4         print('other param', item)
5 
6 
7 import_args('123', 'hello', '2019')

這裡傳遞了3個參數,按位置傳參,'123'為test傳參,'hello'和'2019'為*args傳參,這裡傳了2個參數。

註意,看下麵的*args的另一種用法:用來解壓數據。

1 def import_args(test, *args):
2     print('param1', test)
3     for item in args:
4         print('other param', item)
5 
6 
7 args = ['hello', '2019']
8 import_args('123', *args)

輸出結果:

1 param1 123
2 other param hello
3 other param 2019

 

這段代碼和上面的效果是一樣的,但是這裡第8行的*args和第1行的*args可是不一樣的。第一行是表示函數可以接受不定數量的非鍵值對的參數,用來傳參使用的。第八行是用來解壓列表

['hello', '2019']的每一項數據的,用來解壓參數的。這是*args的兩種用法,也可說是*的兩種用法,因為args是可變的。

 

接下來說說**kwargs。

1 def import_kwargs(test, **kwargs):
2     print('param1', test)
3     for key, value in kwargs.items():
4         print(key, value)
5 
6 
7 d = {'name': 'jack', 'age': 26}
8 import_kwargs('123', **d)

**kwargs用來傳遞帶鍵值對的參數,而**也是用來解壓字典容器內的參數。

輸出結果:

1 param1 123
2 name jack
3 age 26

總結:*args和**kwargs都是用於函數中傳遞參數的,*args傳遞的是非鍵值對的參數,**kwargs傳遞的是帶鍵值對的參數,如果還有普通參數需要傳遞,那麼應該先傳遞普通的參數。

8、
(1)統計如下list單詞及其出現的次數。

a=['apple', 'banana', 'apple', 'tomato', 'orange', 'apple', 'banana', 'watermeton']

方法一:

利用字典。

1 a = ['apple', 'banana', 'apple', 'tomato', 'orange', 'apple', 'banana', 'watermeton']
2 dic = {}
3 for key in a:
4     dic[key] = dic.get(key, 0) + 1
5 print(dic)

輸出結果:

1 {'apple': 3, 'banana': 2, 'tomato': 1, 'orange': 1, 'watermeton': 1}

 

方法二:

利用python的collections包。

1 from collections import Counter
2 
3 a = ['apple', 'banana', 'apple', 'tomato', 'orange', 'apple', 'banana', 'watermeton']
4 d = Counter(a)
5 print(d)

輸出結果:

1 Counter({'apple': 3, 'banana': 2, 'tomato': 1, 'orange': 1, 'watermeton': 1})  # 是一個類似字典的結構
(2)給列表中的字典排序:例如有如下list對象:

alist=[{"name":"a", "age":20}, {"name":"b", "age":30}, {"name":"c", "age":25}] 將alist中的元素按照age從小到大排序。

利用list的內建函數,list.sort()來進行排序。

1 alist = [{"name": "a", "age": 20}, {"name": "b", "age": 30}, {"name": "c", "age": 25}]
2 alist.sort(key=lambda x: x['age'])
3 print(alist)

這是一種效率很高的排序方法。

輸出結果:

1 [{'name': 'a', 'age': 20}, {'name': 'c', 'age': 25}, {'name': 'b', 'age': 30}]
(3)寫出下列代碼的運行結果

第一段代碼的運行結果為:1

分析,在函數外面定義了一個全局變數a為1,在函數內部定義了一個局部變數a為2。局部變數在離開函數後就失效了。

所以,結果為全局變數的a的值。如果在a=2之前加上global a,聲明為全局變數,那麼結果為2。

第二段代碼的運行結果為:[1]

這是因為,將a傳入到function中,這相當於對a進行賦值引用。由於a是可變類型的,所以在函數內部修改a的時候,外部的全局變數a也跟著變化。

第三段代碼的運行結果為:

1 Bob
2 Lily
3 Lily

以上。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 公眾號:SAP Technical 本文作者:matinal 原文出處:http://www.cnblogs.com/SAPmatinal/ 原文鏈接:【MM系列】SAP MM 非限制/可用庫存 前言部分 今天簡單討論一下MM的非限制使用庫存和可用庫存,如果文章有不正確的地方,請及時留言指出,我會第 ...
  • 今天我們來談談 Dubbo XML 配置相關內容。關於這部分內容我打算分為以下幾個部分進行介紹: Dubbo XML Spring 自定義 XML 標簽解析 Dubbo 自定義 XML 標簽解析 DubboBeanDefinitionParser.parse() End Dubbo XML 在本小節 ...
  • 這篇翻譯的不好 如果你看API文檔中的數組篇,你會發現類型一般寫成List.的寫法表示通用類型的數組(未明確指定數組中的數據類型)。通常情況泛型類型用E,T,S,K,V表示。 Why use generics? 為什麼用泛型 泛型是類型安全的(意思是你必須指定數據的類型),但是它的寫法比硬編碼指定類 ...
  • 開場白說點東西: { 抓住客戶的痛點、癢點、爽點,提出我們產品的核心價值。 產品定位 技術架構 以微服務為核心的前後端分離,業務積木裝配式技術架構。感測器採集,物聯網+互聯網轉換,大數據分散式、存儲、計算、可視化加持。消息引擎、搜索引擎、工作流引擎全方位技術支持。 研發模式 Scrum敏捷研發,讓每 ...
  • 本文代碼基於 python3.6 和 pygame1.9.4。 俄羅斯方塊是兒時最經典的游戲之一,剛開始接觸 pygame 的時候就想寫一個俄羅斯方塊。但是想到旋轉,停靠,消除等操作,感覺好像很難啊,等真正寫完了發現,一共也就 300 行代碼,並沒有什麼難的。 先來看一個游戲截圖,有點醜,好吧,我沒 ...
  • vi編輯器是所有Unix及Linux系統下標準的編輯器,它的強大不遜色於任何最新的文本編輯器,這裡只是簡單地介紹一下它的用法和一小部分指令。由於對Unix及Linux系統的任何版本,vi編輯器是完全相同的,因此您可以在其他任何介紹vi的地方進一步瞭解它。Vi也是Linux中最基本的文本編輯器,學會它 ...
  • 列表list初識 列表是python的基礎數據類型之一 ,它是以[ ]括起來, 每個元素用' , '隔開而且可以存放各種數據類型: list列表的定義: 列表的索引和切片操作: 列表的訪問與字元串切片類似,通過索引訪問列表元素,列表的切片也與字元串類似. 列表的常用方法:append():向列表的末 ...
  • 1.原子性: 一個操作或者多個操作,要麼全部執行成功,要麼全部執行失敗。比如賬戶轉賬問題,A賬戶向B轉100,A賬戶減去100元,B賬戶加上一百元,這兩個操作必須具備原子性,才能保證數據的安全,所以需要鎖來保證數據的原子性 2.可見性: 當一個線程修改變數之後,其他線程能夠立即看見修改到的值。比如有 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...