坑的地方是:由於列表用pop以後,後面的索引都會自動減一php
# 列表的坑之一 list1 = ['python','java','php','c','c++','c#','ruby'] # 將索引爲奇數的元素刪除 ['java','c','c#'] list2 = [] for item in list1: if list1.index(item) % 2 != 1: list1.pop(list1.index(item)) print(list1) # ['java', 'php', 'c++', 'c#'] # 這是由於列表用pop以後,後面的索引都會自動減一 # 正確的操做以下: # 切片 list1 = ['python','java','php','c','c++','c#','ruby'] list2 = list1[1::2] print(list2) #['java','c','c#'] # 賦值到其餘的空列表 list1 = ['python','java','php','c','c++','c#','ruby'] list2 = [] for i in list1: if list1.index(i)%2==0: list2.append(i) print(list2) # ['java','c','c#'] # 倒序刪除 list1 = ['python','java','php','c','c++','c#','ruby'] for i in range(len(list1)-1,-1,-1): if i % 2 == 0: del li[i] print(list1) # ['java','c','c#']
# def func(name, sex='男'): # print(name) # print(sex) # # # func('zhouqian') # 輸出的結果爲: # zhouqian # 男
上面的代碼是運行正常的,彷彿默認參數並無什麼坑。可是咱們用下面的例子就知道了。默認參數的陷阱只針對默認參數是可變的數據類型。java
# def func(name, alist=[]): # alist.append(name) # return alist # # # ret = func('zhouqian') # print(ret, id(ret)) # ['zhouqian'] 2135732081224 # ret2 = func('太白金星') # print(ret2, id(ret2))# 按理說是['太白金星'],可是實際上輸出['zhouqian', '太白金星'] 2135732081224 # print(func('zhouqian')) # ['zhouqian'] 2135732081224 # ['zhouqian', '太白金星'] 2135732081224
經過id可知,默認參數是列表的話在內存中是共用同一個地址。只要調用了這個函數,那麼就會在同一個地址後面操做這個元素。若是你的默認參數是可變的數據類型,那麼不管你調用多少次函數,這個默認參數指向的都是同一個地址。若是你給可變的數據類型傳一個值,那麼就不會用原來默認的,就用這個傳值的。python
下面咱們用兩個python的面試題來說解默認參數是可變數據類型的坑。c++
面試題1:面試
def func(a, alist=[]): alist.append(a) return alist print(func(10, )) # [10] print(func(20, [])) # [20] print(func(100, )) # [10,100] # 上面的相似於下面的代碼: # l1 = [] # l1.append(10) # print(l1) # [10] # l2 = [] # l2.append(20) # print(l2) # [20] # l1.append(100) # print(l1) # [10,100]
面試題2:c#
def func(a, alist=[]): alist.append(a) return alist ret1 = func(10, ) # 這裏的值是alist(id 1564531154864) ret2 = func(20, []) # 這裏的值是alist (id 4648456151995) ret3 = func(100, ) # 這裏的值是alist (id 1564531154864) print(ret1) # [10, 100] print(ret2) # [20] print(ret3) # [10, 100] # 上面的相似於下面的代碼: # l1 = [] # l1.append(10) # l2 = [] # l2.append(20) # l1.append(100) # ret1 = l1 # ret2 = l2 # ret3 = l1 # print(ret1) # [10,100] # print(ret2) # [20] # print(ret3) # [10,100]
# count = 1 # def func(): # count += 1 # print(count) # # UnboundLocalError: local variable 'count' referenced before assignment # func() # 解釋:2.局部做用域不能改變全局做用域的變量。當python解釋器讀取到局部做用域時,發現你對一個變量進行了修改的操做,解釋器會認爲你在局部做用域已經定義過這個局部變量,他就從局部找這個局部變量,報錯了。 # 局部和全局做用域的詳細解析 # 1.局部做用域能夠得到到全局做用域中使用變量,從新建立變量,操做變量的賦值,能夠用來對變量進行操做,改變變量的值。 # 2.局部做用域不能改變全局做用域的變量。當python解釋器讀取到局部做用域時,發現你對一個變量進行了修改的操做,解釋器會認爲你在局部做用域已經定義過這個局部變量,他就從局部找這個局部變量,報錯了。 # 3.可是全局做用域不能夠得到局部做用域,不能操做局部做用域的變量,不能操做局部做用域的變量值。 # count = 1 # # 在函數中,若是你定義了一個變量,可是在定義這個變量以前對其引用了,那麼解釋器認爲語法問題。 # 你應該使用以前的先定義後引用。 # def func(): # # 先引用後定義。報錯 # print(count) # UnboundLocalError: local variable 'count' referenced before assignment # count = 3 # # func() # 解釋:在函數中,若是你定義了一個變量,可是在定義這個變量以前對其引用了,那麼解釋器認爲語法問題,你應該使用以前的先定義後引用。 # 如下兩個代碼是不會報錯的。能夠正常運行輸出結果。 # count = 1 # # # def func(): # print(count) # 1 # # count = 3 # 將count=3刪除/註釋掉就不會報錯 # # # func() # count = 1 # # # def func(): # count = 3 # print(count) # 3 # # # func()
# global和nonlocal # 1.在局部做用域聲明一個全局變量 # name = 'alex' # def func(): # name = 'AndreasZhou' # print(name) # func() # print(name) # 輸出的結果爲: # AndreasZhou # alex # 解析:全局變量是從全局名稱空間和內置名稱空間中取值。局部變量是從局部名稱做用域、全局名稱做用域和內置名稱做用域取值。 # 局部名稱做用域---》全局名稱做用域---》內置名稱做用域取值,單向不可逆。 # def func(): # name = 'AndreasZhou' # print(name) # func() # AndreasZhou # print(name) # NameError: name 'name' is not defined # 輸出的結果爲: # AndreasZhou # NameError: name 'name' is not defined # name = 'zhouqian' # def func(): # global name # name = 'AndreasZhou' # print(name) # func() # print(name) # 輸出的結果爲: # AndreasZhou # AndreasZhou # def func(): # global name # name = '太白金星' # print(name) # print(name) # func() # 輸出的結果爲: # NameError: name 'name' is not defined # # 2.修改一個全局變量 # count = 1 # def func(): # # print(count) SyntaxError: name 'count' is used prior to global declaration # global count # count += 1 # print(count) # 1 # func() # # print(count) # 2 # nonlocal # 1.不可以操做全局變量 # count = 1 # def func(): # nonlocal count # SyntaxError: no binding for nonlocal 'count' found # count += 1 # func() # 2.局部做用域:內層函數對外層函數的局部變量進行修改 # def wrapper(): # count = 1 # def inner(): # count+=1 # UnboundLocalError: local variable 'count' referenced before assignment # inner() # wrapper() def wrapper(): count = 1 def inner(): nonlocal count count += 1 print(count) # 1 inner() print(count) # 2 wrapper()