坑的地方是:由于列表用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()