V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ladypxy
V2EX  ›  Python

求助,为什么这两段代码的输出结果是不同的?

  •  
  •   ladypxy · 2019-01-11 20:10:24 +08:00 · 2131 次点击
    这是一个创建于 2147 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先,这样的 2 段代码

    for i in range(1,10):
        for j in range(0,i):
            print(2**j,end=" ")
        print("")
    print("\n")
    
    for i in range(1, 10):
        for i in range(0, i, 1):
            print(2**i,end=" ")
        print("")
    print("\n")
    

    输出均为

    1 
    1 2 
    1 2 4 
    1 2 4 8 
    1 2 4 8 16 
    1 2 4 8 16 32 
    1 2 4 8 16 32 64 
    1 2 4 8 16 32 64 128 
    1 2 4 8 16 32 64 128 256 
    

    然后倒序输出

    for i in range(1,10):
        for i in range(-1+i,-1,-1):
            print(2**i,end=" ")
        print("")
    print("\n")
    
    
    for i in range(1, 10):
        for k in range(-1 + i, -1, -1):
            print(2**k,end=" ")
        print("")
    print("\n")
    

    输出结果都是

    1 
    2 1 
    4 2 1 
    8 4 2 1 
    16 8 4 2 1 
    32 16 8 4 2 1 
    64 32 16 8 4 2 1 
    128 64 32 16 8 4 2 1 
    256 128 64 32 16 8 4 2 1 
    

    但是结合到一起

    for i in range(1,10):
        for j in range(0,i):
            print(2**j,end=" ")
        for k in range(-1+i,-1,-1):
            print(2**k,end=" ")
        print("")
    print("\n")
    
    for i in range(1, 10):
        for i in range(0, i, 1):
            print(2**i,end=" ")
        for i in range(-1 + i, -1, -1):
            print(2**i,end=" ")
        print("")
    print("\n")
    

    结果就变成了

    1 1 
    1 2 2 1 
    1 2 4 4 2 1 
    1 2 4 8 8 4 2 1 
    1 2 4 8 16 16 8 4 2 1 
    1 2 4 8 16 32 32 16 8 4 2 1 
    1 2 4 8 16 32 64 64 32 16 8 4 2 1 
    1 2 4 8 16 32 64 128 128 64 32 16 8 4 2 1 
    1 2 4 8 16 32 64 128 256 256 128 64 32 16 8 4 2 1 
    
    
    1 
    1 2 1 
    1 2 4 2 1 
    1 2 4 8 4 2 1 
    1 2 4 8 16 8 4 2 1 
    1 2 4 8 16 32 16 8 4 2 1 
    1 2 4 8 16 32 64 32 16 8 4 2 1 
    1 2 4 8 16 32 64 128 64 32 16 8 4 2 1 
    1 2 4 8 16 32 64 128 256 128 64 32 16 8 4 2 1
    
    4 条回复    2019-01-11 21:46:16 +08:00
    ClutchBear
        1
    ClutchBear  
       2019-01-11 20:44:17 +08:00
    外层循环的变量是 i
    内层循环的变量也是 i
    pright
        2
    pright  
       2019-01-11 20:57:00 +08:00
    执行第一个 loop
    for i in range(0, i, 1):
    之后 i 的值变成了 i-1

    所以第二个 loop
    for i in range(-1 + i, -1, -1)
    的-1 + i 的值就错了
    ladypxy
        3
    ladypxy  
    OP
       2019-01-11 21:14:31 +08:00
    @pright 多谢,明白了。就是外循环的变量 i,在内循环开始时,其实就相当于常量,也就是内循环的 i 和外循环的 i 不是同一个变量。 而 2 个内循环的 2 个 i,其实是同一个变量。这样理解对吧
    pright
        4
    pright  
       2019-01-11 21:46:16 +08:00
    所有的 i 都是同一个变量,关键其实是外层 loop 执行时 i 的值会被改写回来,要解释的话应该是
    外层 loop
    for i in range(1, 10)
    生成一个[1, 2, ..., 9]的 list,依次给 i 赋值,假设执行到 i=2,往下执行。
    第一层 loop
    for i in range(0, i, 1)
    先解析 range(0, i, 1),此时 i 的值是外层 loop 传下来的 i 的值 2,之后生成了一个[0, 1]的 list,list 中的每个元素都会给 i 赋值,改变 i 的值,直到 loop 完,此时 i 的值为 1。
    第二层 loop
    for i in range(-1 + i, -1, -1)
    同样解析 range(-1 + i, -1, -1),此时 i 的值是刚刚得到的 1,所以生成了一个[0]的 list,给 i 赋值
    之后回到外层 loop,list 继续给 i 赋值成 3,继续运行。

    官方说明
    https://docs.python.org/dev/reference/compound_stmts.html#for
    The for-loop makes assignments to the variables in the target list. This overwrites all previous assignments to those variables including those made in the suite of the for-loop:
    for i in range(10):
    print(i)
    i = 5 # this will not affect the for-loop
    # because i will be overwritten with the next
    # index in the range
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5587 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 06:46 · PVG 14:46 · LAX 22:46 · JFK 01:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.