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
kevinroot
V2EX  ›  Python

为毛 python 没有自增自减运算?

  •  
  •   kevinroot ·
    adin283 · 2014-02-19 12:35:35 +08:00 · 16079 次点击
    这是一个创建于 3912 天前的主题,其中的信息可能已经有所发展或是发生改变。
    每次写到count += 1就ju花一紧
    42 条回复    2016-03-07 19:15:31 +08:00
    dorentus
        1
    dorentus  
       2014-02-19 12:42:52 +08:00
    因为不好看……
    hitsmaxft
        2
    hitsmaxft  
       2014-02-19 12:44:23 +08:00 via iPhone
    因为作者很懒
    loading
        3
    loading  
       2014-02-19 12:46:35 +08:00 via iPhone
    难道你还怀念考C语言
    i++
    ++i
    的头晕日子?

    程序是给人看的!
    tonitech
        4
    tonitech  
       2014-02-19 12:50:08 +08:00   ❤️ 1
    举个例子
    foo=1
    bar=1
    foo现在和bar的地址实际上是相同的,
    当foo+1变成2之后,它的那个啥,地址就跟之前不一样了。。。
    应该说是概念不同吧。。。
    chevalier
        5
    chevalier  
       2014-02-19 12:59:18 +08:00
    i++ 这种操作在C刚诞生的那会,很有用,因为相对于i=i+1可以节约两个字节的空间,那时候的内存真的在乎这两个字节。后来其他语言如Java只不过考虑到程序员的习惯沿用了这一用法。
    在今天,已经不用考虑这两个字节了,为了程序的可读性,还是写成i=i+1比较好,Python中就去掉i++这种用法了。
    VYSE
        6
    VYSE  
       2014-02-19 13:08:17 +08:00   ❤️ 3
    http://stackoverflow.com/questions/3654830/why-are-there-no-and-operators-in-python

    我觉得第二个回答很好,++ -- 更多是为了让当年不聪明的编译器翻译成 inc operand / dec operand 而不是俩mov然后add
    今天则不需要,结果养成了一种病
    est
        7
    est  
       2014-02-19 13:25:44 +08:00
    @VYSE python的 += 1 依然不是原子操作。。。。。
    VYSE
        8
    VYSE  
       2014-02-19 13:34:18 +08:00
    @est 有GIL保障就好,毕竟不是native的
    chilaoqi
        9
    chilaoqi  
       2014-02-19 13:55:25 +08:00
    python 追求 readability
    ivenvd
        10
    ivenvd  
       2014-02-19 14:08:36 +08:00
    因为 Python 基本上用不到自加自减,不是么?
    tonitech
        11
    tonitech  
       2014-02-19 14:09:44 +08:00
    @VYSE 但是我觉得++很优美啊。。。
    tonitech
        12
    tonitech  
       2014-02-19 14:10:38 +08:00
    @chilaoqi ++去掉就提升了readability吗?
    yegle
        13
    yegle  
       2014-02-19 14:11:15 +08:00
    @est 我靠!不是原子操作是个什么情况!!!
    Ever
        14
    Ever  
       2014-02-19 14:12:51 +08:00
    python的数值是immutable的.
    zzNucker
        15
    zzNucker  
       2014-02-19 14:13:25 +08:00   ❤️ 1
    看到楼主写的ju花一紧,下意识看了下tag
    yegle
        16
    yegle  
       2014-02-19 14:24:17 +08:00   ❤️ 1
    补充14楼 @Ever的说明

    In [35]: i = 1

    In [36]: id(i)
    Out[36]: 4474635968

    In [37]: i = 2

    In [38]: id(i)
    Out[38]: 4474636000

    In [39]: i = 1

    In [40]: id(i)
    Out[40]: 4474635968
    oio
        17
    oio  
       2014-02-19 14:25:05 +08:00
    看了一下,i += 1 用的是 INPLACE_ADD, i = i+1 用的是 BINARY_ADD, 这两者效率有区别?具体实现是不是得看Cpython源码....
    est
        18
    est  
       2014-02-19 14:32:01 +08:00
    @yegle

    如果没记错的话

    http://effbot.org/zone/thread-synchronization.htm

    > The reason for this is that the increment operation is actually executed in three steps;

    python解释器有很多脑残举动。。。比如代码里 1+1 可以自动优化成一个常量但是1 + 2 * 3就不行。


    >>> from dis import dis
    >>> def f(): return 1 + 2 * 3
    >>> dis(f)




    大家可以自己去python看看结果。v2ex贴代码比较乱就不贴了。反正笑死人了。
    oldcai
        19
    oldcai  
       2014-02-19 14:33:44 +08:00
    python很多东西都没有:还比如switch,条件语句里面的赋值。
    当然,以及楼主所说的++和--,这些在刚转入python的时候是让人很不习惯,我也吐槽过,但是习惯了也就好了,有其他办法实现目的。

    @chevalier 编译后都是一样的,省不到,只是让编码减少一点而已。
    est
        20
    est  
       2014-02-19 14:42:20 +08:00
    @oldcai 这个倒是有啊

    func_map = {value1: func1, value2: func2}

    func_map.get(my_value, default_func)(*args, **kwargs)

    巨型分支效率比switch高

    哈哈哈哈。。。
    luckwang
        21
    luckwang  
       2014-02-19 14:54:29 +08:00
    用for的话有个enumerate()
    sandtears
        22
    sandtears  
       2014-02-19 14:57:54 +08:00
    因为作者不喜欢
    BOYPT
        23
    BOYPT  
       2014-02-19 15:04:27 +08:00   ❤️ 1
    在python里面找编码效率问题,你还真是找对了地方。
    davidli
        24
    davidli  
       2014-02-19 15:49:16 +08:00
    上面那个stackoverflow链接里的回答很有道理。
    i++平时就主要用在for语句里,而在Python里for语句直接用range()了,i++ ++i这种不够直观又容易出错的用法就没必要出现了。
    oldcai
        25
    oldcai  
       2014-02-19 15:56:03 +08:00
    @est 是啊,我也是用的这个方法实现原先需要switch的功能。
    比起switch,这个不用只拘泥于数字类型。
    至于效率,都用脚本了,就不要那么计较了吧(啊喂,为什么不用ruby用python(找骂))。
    而且,到计较switch不满足条件会遍历条件的效率的时候,也会有其他的实现方式了。
    qazwsxedc121
        26
    qazwsxedc121  
       2014-02-19 16:07:46 +08:00
    我现在写js都绝对不写 ++ ,写 += 1 了,蝴蝶书里面说的我感觉很有道理
    FrankFang128
        27
    FrankFang128  
       2014-02-19 16:19:51 +08:00
    令人误解,不用也罢。
    liubin
        28
    liubin  
       2014-02-19 16:55:20 +08:00
    @VYSE 不加锁没有哪种语言会把++作为原子操作去实现吧。
    jiang42
        29
    jiang42  
       2014-02-19 17:12:49 +08:00
    每种语言都有各自的优劣
    想要自增自减大可以用C
    程序是写给人看的,不过计算机恰好能读懂而已
    BTW,python 是社区在进行开发,你可以去提出 issue 叫他们增加自增自减
    有没人愿意这么做就不知道了-。-
    kunimi
        30
    kunimi  
       2014-02-19 17:44:45 +08:00   ❤️ 1
    @yegle 这个例子还是有一定误导性的,对于整型变量来说,python其实定义了一个小整数池(-5到257),在这个范围内,如果对两个变量赋值同一个值,那么它们指向的是同一个对象。
    In [1]: i=258

    In [2]: j=258

    In [3]: id(i)
    Out[3]: 42930796

    In [4]: id(j)
    Out[4]: 42932492
    luoqeng
        31
    luoqeng  
       2014-02-19 18:21:46 +08:00
    @chevalier
    A (false) folk myth is that the instruction set architecture of the PDP-11 influenced the idiomatic use of the B programming language. The PDP-11's increment and decrement addressing modes correspond to the −−i and i++ constructs in C. If i and j were both register variables, an expression such as *(−−i) = *(j++) could be compiled to a single machine instruction. Dennis Ritchie unambiguously contradicts this folk myth, noting that the PDP-11 did not yet exist at the time of B's creation. He notes however that these addressing modes may have been suggested by the auto-increment cells of the PDP-7, though the implementation of B did not utilize this hardware feature.[4] The C programming language did however take advantage of several low level PDP-11 dependent programming features, resulting in the propagation of these features into new processors.

    http://en.wikipedia.org/wiki/PDP-11_architecture

    《C专家编程》里面好像也有讲
    jakwings
        32
    jakwings  
       2014-02-19 18:33:51 +08:00
    我觉得看完上面的所有评论才应该菊花一紧……不敢玩 Python 代码风格了怎么办?@est
    est
        33
    est  
       2014-02-19 19:06:46 +08:00
    @liubin 也不绝对。x86指令集支持这个 http://en.wikipedia.org/wiki/Fetch-and-add
    wodemyworld
        34
    wodemyworld  
       2014-02-19 19:11:31 +08:00
    没原生swith这个确实一开始不太能习惯
    VYSE
        35
    VYSE  
       2014-02-19 20:12:45 +08:00
    @liubin INC寄存器是原子的,要原子INC内存里一变量就得LOCK INC/DEC在X86,GCC里得用atomic系列函数搞,不知道其他编译器怎么选择
    workaholic
        36
    workaholic  
       2014-02-19 20:33:44 +08:00 via Android
    概念不同,python中数字和字符都是改变后就变了地址,前后加减操作给人错觉就是没有变地址
    weakish
        37
    weakish  
       2014-02-19 20:41:37 +08:00
    Lua里面连`+=`也没有……
    picasso250
        38
    picasso250  
       2014-02-20 09:42:34 +08:00
    there is one way to do one thing
    yegle
        39
    yegle  
       2014-02-20 11:00:28 +08:00
    另外,真的不试试enumerate函数吗…
    fghzpqm
        40
    fghzpqm  
       2014-02-20 11:25:42 +08:00
    @VYSE GIL 并不能保证 a += 1 是原子的。 cc @est
    VYSE
        41
    VYSE  
       2014-02-20 16:25:53 +08:00
    @fghzpqm 恩,GIL的确不行,itertools.count应该可以thread safe
    biby
        42
    biby  
       2016-03-07 19:15:31 +08:00
    好奇,先跟随写法,以后再思考
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   999 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 21:22 · PVG 05:22 · LAX 13:22 · JFK 16:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.