python学习之while循环

今日温故知新内容

python底层数据存放知识延伸——数据的深拷贝和浅拷贝

有如下需求,通过复制一个列表得到另一个列表,对其中一个列表进行任意的改操作,完全不会影响到另一个列表,也就是说复制得到的列表是完全独立的

首先,我们试下如下操作:

list01 = ['tom','susan',[11,22]]
list02 = list01
list01[2][0] = 111
list02[2][1] = 222
print(list01)
#['tom', 'susan', [111, 222]]
print(list02)
#['tom', 'susan', [111, 222]]

上面的操作,其实就是变量的赋值,和拷贝半毛钱关系都没有;

list02 = list01本质上就是在内存栈区将变量名list01与列表['tom','susan',[11,22]]内存地址的对应关系复制了一份,直接丢给了变量list02,在堆区中没有发生任何事情,又何来拷贝一说,实际过程如下图所示。

list01和list02引用的是堆区中的同一个内存地址,相当于一个人有两个不同的名字。

根据上面的信息来运行python中的copy操作,代码如下:

list01 = ['tom','susan',[11,22]]
list02 = list01.copy()
print(id(list01),id(list01[0]),id(list01[1]),id(list01[2]))
#38881792 38856368 38856688 38856064
print(id(list02),id(list02[0]),id(list02[1]),id(list02[2]))
#39511232 38856368 38856688 38856064
list01[0] = 'egon'
list02[1] = 'alex'
list01[2][0] = 111
list02[2][1] = 222
print(list01)
#['egon', 'susan', [111, 222]]
print(list02)
#['tom', 'alex', [111, 222]]

list02 = list01.copy()是python中的浅拷贝操作;从list02和list01内存地址不一样,可以看出copy操作在堆区中开辟了一个全新的内存空间;而从所有元素的id一模一样可以看出,新的内存空间存的内容与原来的是一模一样的;

对于不可变类型来说,对它进行了直接引用,如果对其修改,必定指向新的内存地址,因此不会影响另外一个列表的值;这一点可以从list01、list02最后的打印结果进行验证。

而对于可变类型(容器类型)来说,对它进行的是间接引用,如果对其修改,只是修改了容器内单个元素指向的内存地址,它本身的内存地址没有发生变化,另外一个列表仍然对它进行了引用,因此另一个列表的值也会发生变化。这一点可以从list01、list02最后的打印结果进行验证。

copy操作并不能实现需求,最后再实验一下deepcopy操作。

import copy
list01 = ['tom','susan',[11,22]]
list02 = copy.deepcopy(list01)
print(id(list01),id(list01[0]),id(list01[1]),id(list01[2]))
#39511616 38855920 38856688 39579712
print(id(list02),id(list02[0]),id(list02[1]),id(list02[2]))
#39697408 38855920 38856688 39696768
list01[0] = 'egon'
list02[1] = 'alex'
list01[2][0] = 111
list02[2][1] = 222
print(list01)
#['egon', 'susan', [111, 22]]
print(list02)
#['tom', 'alex', [11, 222]]

list02 = copy.deepcopy(list01)是python中的深拷贝操作;从list02和list01内存地址不一样,可以看出copy操作在堆区中开辟了一个全新的内存空间;deepcopy将可变和不可变类型进行了区分,把列表中不可变类型元素的内存地址对应关系完整复制了一份,将可变类型元素的索引指向新的内存地址。这样改变操作最终只作用到了不可变类型身上,原列表和拷贝的列表互不影响。

1、while循环的语法与基本使用

print(1)
while 条件:
代码1
代码2
代码3
print(3)

count=0
while count < 5: # 5 < 5
    print(count) # 0,1,2,3,4
    count+=1 # 5

print('顶级代码----->')

2、死循环与效率问题

count=0
while count < 5: # 5 < 5
    print(count) # 0,1,2,3,4

while True:
    name=input('your name >>>> ')
    print(name)

纯计算无io的死讯会导致致命的效率问题
while True:
1+1

while 1:
print('xxxx')

3、循环的应用

两个问题:
1)重复代码
2)输对了应该不用再重复

username = 'egon'
password = '123'
while True:
    inp_name=input('请输入您的账号:')
    inp_pwd=input('请输入您的密码:')

    if inp_name  == username and inp_pwd == password:
        print('登录成功')
    else:
        print('账号名或密码错误')

4、退出循环的两种方式

方式一:将条件改为False,等到下次循环判断条件时才会生效

tag=True
while tag:
    inp_name=input('请输入您的账号:')
    inp_pwd=input('请输入您的密码:')

    if inp_name  == username and inp_pwd == password:
        print('登录成功')
        tag = False # 之后的代码还会运行,下次循环判断条件时才生效
    else:
        print('账号名或密码错误')

    # print('====end====')

方式二:break,只要运行到break就会立刻终止本层循环

while True:
    inp_name=input('请输入您的账号:')
    inp_pwd=input('请输入您的密码:')

    if inp_name  == username and inp_pwd == password:
        print('登录成功')
        break # 立刻终止本层循环
    else:
        print('账号名或密码错误')

    # print('====end====')

5、while循环嵌套与结束

'''
tag=True
while tag:
while tag:
while tag:
tag=False

每一层都必须配一个break
while True:
while True:
while True:
break
break
break
'''
break的方式

while True:
    inp_name=input('请输入您的账号:')
    inp_pwd=input('请输入您的密码:')

if inp_name  == username and inp_pwd == password:
    print('登录成功')
    while True:
        cmd=input("输入命令>: ")
        if cmd == 'q':
            break
        print('命令{x}正在运行'.format(x=cmd))
    break # 立刻终止本层循环
else:
    print('账号名或密码错误')

# print('====end====')

改变条件的方式

tag=True
while tag:
    inp_name=input('请输入您的账号:')
    inp_pwd=input('请输入您的密码:')

if inp_name  == username and inp_pwd == password:
    print('登录成功')
    while tag:
        cmd=input("输入命令>: ")
        if cmd == 'q':
            tag=False
        else:
            print('命令{x}正在运行'.format(x=cmd))
else:
    print('账号名或密码错误')

6、while +continue:结束本次循环,直接进入下一次

强调:在continue之后添加同级代码毫无意义,因为永远无法运行

count=0
while count < 6:
    if count == 4:
        count+=1
        continue
        # count+=1 # 错误
    print(count)
	count+=1

7、while +else:针对break

count=0
while count < 6:
    if count == 4:
        count+=1
        continue
    print(count)
    count+=1
else:
    print('else包含的代码会在while循环结束后,并且while循环是在没有被break打断的情况下正常结束的,才会运行')
count=0
while count < 6:
    if count == 4:
        break
    print(count)
    count+=1
else:
    print('======>')

8、应用案列:

版本1:

count=0
tag=True
while tag:
    if count == 3:
        print('输错三次退出')
        break
    inp_name=input('请输入您的账号:')
    inp_pwd=input('请输入您的密码:')

if inp_name  == username and inp_pwd == password:
    print('登录成功')
    while tag:
        cmd=input("输入命令>: ")
        if cmd == 'q':
            tag=False
        else:
            print('命令{x}正在运行'.format(x=cmd))
else:
    print('账号名或密码错误')
    count+=1

版本2:优化

count = 0
while count < 3:
    inp_name = input('请输入您的账号:')
    inp_pwd = input('请输入您的密码:')

    if inp_name == username and inp_pwd == password:
        print('登录成功')
        while True:
            cmd = input("输入命令>: ")
            if cmd == 'q':  # 整个程序结束,退出所有while循环
                break
            else:
                print('命令{x}正在运行'.format(x=cmd))
        break
    else:
        print('账号名或密码错误')
        count += 1

else:
    print('输错3次,退出')


posted @ 2020-03-10 00:50  慆慢险躁  阅读(111)  评论(0编辑  收藏  举报