zoukankan      html  css  js  c++  java
  • python的坑--你知道吗?

    python的坑--你知道吗?

    1.列表的坑

    坑的地方是:因为列表用pop之后,后面的索引都会自动减一

    # 列表的坑之一
    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#']
    

    2.默认参数的陷阱

    # def func(name, sex='男'):
    #     print(name)
    #     print(sex)
    #
    #
    # func('zhouqian')
    # 输出的结果为:
    # zhouqian
    # 男
    

    上面的代码是运行正常的,仿佛默认参数并没有什么坑。但是我们用下面的例子就知道了。默认参数的陷阱只针对默认参数是可变的数据类型

    # 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的面试题来讲解默认参数是可变数据类型的坑。

    面试题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:

    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]
    

    3.局部作用域的陷阱

    # 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()
    

    4.补充知识点:global和nonlocal

    # 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()
    
  • 相关阅读:
    Gym
    struts2.5 使用感叹号和通配符实现动态方法调用无效的问题及解决!
    Offfice 多重版本key残留并存的异常问题
    IDEA Struts2 truts-default显红的解决办法
    Struts2的库在 IDEA 的外联库就会报错,不知道为什么。
    计算机二级python 知识点篇(第三方库)
    计算机二级python 知识点篇(python标准库)
    计算机二级python 知识点篇(内置函数整理)
    计算机二级python 知识点篇(文件和数据格式化)
    计算机二级python 知识点篇(组合数据类型)
  • 原文地址:https://www.cnblogs.com/stu-zhouqian/p/13159239.html
Copyright © 2011-2022 走看看