【Python基础复习】那些容易踩坑的诡异操作

学习自华为云学院白泽老师《Python入门篇》课程

生成器

(i for i in range(10))
 at 0x000001F6CB7E1AC0>

相互引用产生死循环

a = [1,2,3]
b = [3,4,5]

a.append(b)
b.append(a)
print(a)
print(b)
[1, 2, 3, [3, 4, 5, [...]]]
[3, 4, 5, [1, 2, 3, [...]]]
a = [""]*3
b = [a]*3
b[1][1] = 0
print(a)
print(b)
['', 0, '']
[['', 0, ''], ['', 0, ''], ['', 0, '']]
a, b = {}, 5
a[b] = a, b
print(a)
{5: ({...}, 5)}

lambda表达式&排序

# 排序
l = [(1, 2), (2, 4), (2, 3), (3, 2)]
l.sort(key=lambda x:(x[0],x[1]))
l
[(1, 2), (2, 3), (2, 4), (3, 2)]
# 列表删除元素
s = [99,100,46,44,68,50,59,50,59,66,89,54]
for i in s:
    if i < 60:
        s.remove(i)
        
s #有问题 [99, 100, 44, 68, 59, 59, 66, 89]
[99, 100, 44, 68, 59, 59, 66, 89]
# 列表删除元素
s = [99,100,46,44,68,50,59,50,59,66,89,54]
for i in s:
    if i < 60:
        s.pop(i)
s #IndexError: pop index out of range
---------------------------------------------------------------------------

IndexError                                Traceback (most recent call last)

 in 
      3 for i in s:
      4     if i < 60:
----> 5         s.pop(i)
      6 s


IndexError: pop index out of range

列表在每一次循环当中都会动态变化,当元素被删,循环的列表索引下标发生改变,会直接影响循环过程

解决方法1:创建一份浅拷贝

import copy
s = [99,100,68,59,50,59,66,89,54]
s1 = copy.copy(s)
for i in s:
    if i < 60:
        s1.remove(i)
        
s1
[99, 100, 68, 66, 89]

解决方法2:列表推导式


import copy
s = [99,100,46,44,68,50,59,50,59,66,89,54]
[ i for i in s if i>=60 ]
[99, 100, 68, 66, 89]

解决方法3:倒着删,删除后避免元素迁移导致索引变化


s = [99,100,46,44,68,50,59,50,59,66,89,54]
for i in range(len(s)-1, -1, -1):
    print(i,":", s[i])
    if s[i] < 60:
        print('removing...')
        s.pop(i)
s
11 : 54
removing...
10 : 89
9 : 66
8 : 59
removing...
7 : 50
removing...
6 : 59
removing...
5 : 50
removing...
4 : 68
3 : 44
removing...
2 : 46
removing...
1 : 100
0 : 99





[99, 100, 68, 66, 89]

解决方法4:filter函数 + lambda表达式

s = [99,100,46,44,68,50,59,50,59,66,89,54]
list(filter(lambda x:x>=60, s))
[99, 100, 68, 66, 89]

浅拷贝和深拷贝

l = [1,2,3,[5,4]]
l1 = l.copy() #copy方法实现浅拷贝
import copy
l2 = copy.deepcopy(l)
l == l1 == l2
True
l1 is l
False
l2 is l
False
l1[3][1]=6
l
[1, 2, 3, [5, 6]]
l1
[1, 2, 3, [5, 6]]
l2
[1, 2, 3, [5, 4]]

诡异的运算符使用方法

不推荐,仅了解

(False == False) in [False]
False
False == (False in [False])
False
False == False in [False]
True
True is False == False
False
False is False is False
True
1 > 0 < 1  #等价于 1>0 and 0<1
True
(1 > 0 ) < 1
False
1 > (0 < 1)
False

操作符优先级:**最高, and or not最小

指定i不能打断循环

循环产生迭代器,循环只不过遍历已经生成完数值

# 循环产生迭代器,循环只不过遍历已经生成完数值
for i in range(4):
    print(i)
    i = 10
0
1
2
3

代码效率问题

# 判断是否感染新冠
COVID = 1  
if COVID:#避免没有必要的计算执行
    print("请隔离治疗")
else:
    print("通过")
请隔离治疗
# 排序
import random
l = [i for i in range(10)]
random.shuffle(l)
l
[7, 1, 8, 4, 5, 6, 9, 0, 2, 3]
temp = []

n = len(l)
for i in range(n):
    s = l[0]
    for i in range(len(l)):
        if l[i] < s:
            s = l[i]
            
    print(l)
    l.remove(s)
    temp.append(s)
    
    
temp
[7, 1, 8, 4, 5, 6, 9, 0, 2, 3]
[7, 1, 8, 4, 5, 6, 9, 2, 3]
[7, 8, 4, 5, 6, 9, 2, 3]
[7, 8, 4, 5, 6, 9, 3]
[7, 8, 4, 5, 6, 9]
[7, 8, 5, 6, 9]
[7, 8, 6, 9]
[7, 8, 9]
[8, 9]
[9]





[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

空间复杂度换时间复杂度

def quick_sort(arr):
    if len(arr) < 2:
        return arr
    # 选取基准,随便选哪个都可以,选中间的便于理解
    mid = arr[len(arr) // 2]
    # 定义基准值的左右两个数列
    left, right = [], []
    # 从原始数组中移除基准值
    arr.remove(mid)
    for item in arr:
        #大于基准值放右边
        if item >= mid:
            right.append(item)
        else:
            left.append(item)
    #使用递归迭代进行比较
    return quick_sort(left) + [mid] + quick_sort(right)

quick_sort([1, 10, 9, 5, 8, 0])
[0, 1, 5, 8, 9, 10]

装饰器

import time
def func(f):
    def inner(*args, **kwargs):
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        print('耗时:%s秒' % (end_time - start_time))
    return inner
# 装饰器就是在不改变原本代码情况下加入新的功能
@func
def test():
    time.sleep(1)

#相当于    
#func(test())

你可能感兴趣的:(【Python基础复习】那些容易踩坑的诡异操作)