- 簡答題
1、請談談Python中is 和 == 的區別(代碼演示)
is用於比較兩個變量是否引用了同一個內存地址,is表示的是對象標識符(object identity),作用是用來檢查對象的標識符是否一致,也就是比較兩個對象在內存中的地址是否一樣。
==用於比較兩個變量的值是否相等,==表示的是相等(equality)。
is是檢查兩個對象是否指向同一塊內存地址,而==是檢查他們的值是否相等。
可以看出,is是比==更嚴格的檢查,is返回True表明兩個對象指向同一塊內存,值也一定相同。
# case 1:對於數值型和字符串型對象, python的存儲機制使得a和b其實指向同一個地址,所以is和==都是True a = 7 b = 7 print("a和b是int型") print("a的地址是", id(a)) print("b的地址是", id(b)) # 比較地址 print("a和b的地址值相同?", a is b) # 比較值 print("a和b的數值相同?", a == b)
a和b是int型 a的地址是 139947890484128 b的地址是 139947890484128 a和b的地址值相同? True a和b的數值相同? True
# case 2:對於list、tuple等容器,a和b雖然內容一樣,但是是兩個不同的對象引用,指向兩個不同的內存地址 a = [1, 2, 3] b = [1, 2, 3] print("a和b是列表") print("a的地址是", id(a)) print("b的地址是", id(b)) # 比較地址 print("a和b的地址值相同?", a is b) # 比較值 print("a和b的數值相同?", a == b) print("*"*20) a = (1, 2, 3) b = (1, 2, 3) print("a和b是元組") print("a的地址是", id(a)) print("b的地址是", id(b)) # 比較地址 print("a和b的地址值相同?", a is b) # 比較值 print("a和b的數值相同?", a == b)
a和b是列表 a的地址是 139947465543432 b的地址是 139947786638728 a和b的地址值相同? False a和b的數值相同? True ******************** a和b是元組 a的地址是 139947474361656 b的地址是 139947474360072 a和b的地址值相同? False a和b的數值相同? True
# case 3:實際上可以通過修改對象的__eq__方法改變==的比較方式 # 對象相等的判斷 # python中的對象是否相等有兩個層面, # 一個層面是是否是同一個對象,及在內存中是否共用一個內存區域,用is判斷,另一個是對象的值是否相等,用==判斷。 # 比較兩個python對象是否相等,看個例子: class student(object): def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def __eq__(self, *args, **kwargs): return object.__eq__(self, *args, **kwargs) like = student("like", 25, "male") xue = student("xue", 23, "female") dong = student("like", 25, "male") print(like is xue) # False print(like is dong) # False print(like == dong) # False # 這里有兩個student類的實例化對象,like和xue很明顯是兩個不同的對象,他們的不同體現在所占內存地址不同且對象的屬性也不同。 # ************************************************************************ # like和dong雖然屬性相同,但是is和==兩種判斷的結果也都為false, # 在實際情況中,我們大多都希望like和dong屬性相同,就認為是同一個對象,所以我們需要重寫類的eq方法: class student(object): def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def __eq__(self,other): return self.__dict__ == other.__dict__ # return self.name == other.name like = student("like",25,"male") dong = student("like",25,"male") print(like == dong) # True # 調用一個對象的dict方法可以用字典的形式輸出其屬性列表,由於兩個對象的屬性相同,所以==運算為True。 # ************************************************************************ # 自定義python對象相等的條件 # 當然在實際情況下,可以更靈活的定義兩個對象相等的條件,比如名字一樣就認為相等。 class student(object): def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def __eq__(self,other): return self.name == other.name like = student("like", 25, "male") dong = student("like", 23, "female") print(like == dong) # True # ************************************************************************ # 在實際應用中,有一個場景是處理對象是否在list里,不在就加入。 like = student("like", 25, "male") dong = student("like", 25, "male") list1 = [] list1.append(like) if dong not in list1: list1.append(dong) print(len(list1)) # 1
False False False True True 1
2、Python中的高階函數是指什么
map、reduce、filter、zip這類函數
2.1、map()
map() 顧名思義,map函數的作用是映射。python源碼解釋如下:
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted.
簡單來說,
map()它接收一個函數 f 和一個可迭代對象(這里理解成 list),並通過把函數 f 依次作用在 list 的每個元素上,得到一個新的 list 並返回。
注意:map()函數不改變原有的 list,而是返回一個新的 list。
# 舉例: _list = [1, 2, 3] def f(x): return x * x # map(f, _list) # map at 0x7f43e045dba8> print(list(map(f, _list))) # 通過map,完成了對列表每個元素開平方的功能 # 結合匿名函數使用,實現功能同上 print(list(map(lambda x: x * x, _list))) # 任務 # 假設用戶輸入的英文名字不規范,沒有按照首字母大寫,后續字母小寫的規則, # 請利用map()函數,把一個list(包含若干不規范的英文名字)變成一個包含規范英文名字的list: list_ = ['lll', 'lKK', 'wXy'] def f_(abc): ''' 首字母大寫,后續字母小寫 ''' return abc[0:1].upper() + abc[1:].lower() # return abc.capitalize() print(list(map(f_, list_)))
[1, 4, 9] [1, 4, 9] ['Lll', 'Lkk', 'Wxy']
2.2、reduce()
reduce()和map()類似,但是reduce()傳入的函數 f 必須接收兩個參數,而且reduce()還要導包。。。差評
# 舉例 from functools import reduce ## 累加求和,小學經典的求前100個數的問題。。。 def add(x, y): return x + y print(reduce(add, [i for i in range(1, 101)])) # 匿名函數實現同樣功能 print(reduce(lambda x, y: x + y, [i for i in range(1, 101)]))
5050 5050
2.3、filter()
顧名思義,過濾用的函數,用法同map()類似,filter()函數接收一個函數 f 和一個list,只不過這里的f起到的是判斷的作用,符合條件的留下,不符合的丟掉
# 舉例 # 過濾列表中所有能被3乘除的數和等於2的數 list_ = [-9, -7, -6, 0, 2, 16, 99] def f(x): if x % 3 == 0: return x # 非0即真,這里的0認為是false,無法被選中 elif x == 2: # x == 0。。。抑郁了 return x # filter(f, list_) # <filter at 0x7f43e0308b70> list(filter(f, list_))
[-9, -6, 2, 99]
2.4、zip()
zip函數接受任意多個可迭代對象作為參數,將對象中對應的元素打包成一個tuple,然后返回一個可迭代的zip對象
# 舉例 a1=[1,2,3] a2=[4,5,6] a3=[7,8,9] a4=["a","b","c","d"] zip1 = zip(a1,a2,a3) print(zip1) # <zip object at 0x7f43e03def08> # print(list(zip1)) # 這里變成list的話,直接輸出[(1, 4, 7), (2, 5, 8), (3, 6, 9)],下面的for循環就沒有輸出了 print("*"*20) for i in zip1: print(i) print("*"*20) # 這個可迭代對象可以使用循環的方式列出其元素 # 若多個可迭代對象的長度不一致,則所返回的列表與長度最短的可迭代對象相同. zip2 = zip(a1, a4) # print(list(zip2)) for i in zip2: print(i)
<zip object at 0x7f480ef99788> ******************** (1, 4, 7) (2, 5, 8) (3, 6, 9) ******************** (1, 'a') (2, 'b') (3, 'c')
3、Python類中有哪些的成員,如何分類他們,他們各自又有哪些用途?
python是一種以面向對象為思想的編程語言,面向對象的核心在於,一切皆對象,而對象由兩部分組成,屬性 + 方法。
python類中包括了類屬性(即類變量)、類方法、成員屬性(實例屬性)、成員函數(實例方法)、靜態方法。
比如我們構建動物類 class Animal,這個Animal類可以有體重,顏色等類屬性,當實例化Animal類的實例對象時,
這些類屬性是共用的(實例對象共用),同理類方法也是這個意思。而Animal類在構建的時候有一種魔法方法成為構造方法,"_init_",
它會在實例化對象的時候給每個對象初始化不同的實例屬性,這個是每個成員獨有的。
而在Animal類其中所寫的任何(不加裝飾器)類似python函數(def開頭的...)的方法都是實例方法,他們是類實例化對象所共有的方法。
對於類方法和靜態方法,都是在def前面加上裝飾器(@classmethod和@staticmethod),類方法即類和對象都可以用,
靜態方法類似於普通函數,不僅該類和對象共用靜態方法主要是用來存放邏輯性的代碼,邏輯上屬於類,但是和類本身沒有關系,
也就是說在靜態方法中,不會涉及到類中的屬性和方法的操作。可以理解為,靜態方法是個獨立的、單純的函數,它僅僅托管於某個類的名稱空間中,便於使用和維護。
4、Python中列表,元組的相同之處及區別都有哪些?集合與字典呢?
列表、元組、集合、字典都是python中的容器,可以存大量單獨的int,str等數據。
列表和元組相同點:1、有序,2、都是一種序列,3、都是可迭代對象,都支持索引切片等操作
不同點:列表是可變數據類型,元組是不可變數據類型
集合和字典相同點:都是無序的
不同點:1、集合中不存重復相同的元素,2、字典中所存的元素都是鍵值對一一對應的,是以哈希表為基礎的映射關系