推荐学习书目
› 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
loliordie
V2EX  ›  Python

简洁优雅 pythonic 的代码风格和更容易阅读的代码风格你更倾向哪一种?

  •  
  •   loliordie · Sep 27, 2020 · 4933 views
    This topic created in 2237 days ago, the information mentioned may be changed or developed.

    这个起因非常神奇, 是我跟另一位 dalao 刷 LC 一道 EASY 题时产生的讨论.

    题目 LC. 234 的 O(1)空间复杂度解法, 由于是三刷我们的思路完全一致, 都是利用回文对称性寻找中间点的同时将前半部分指向关系翻转后进行比较, 但代码风格的不同却造成了别人阅读代码的不同反应.

    这是大佬的解答部分代码, 非常 pythonic, 可以看出使用了好几个骚操作来压缩代码.

    fast, slow, pre = head, head, None
    while fast and fast.next:
        fast = fast.next.next
        pre, slow.next, slow = slow, pre, slow.next
    slow = slow.next if fast else slow
    while slow and slow.val == pre.val:
        pre, slow = pre.next, slow.next
    return not pre
    

    这是我的烂代码

    fast = head
    slow = head
    pre = None
    
    while fast and fast.next:
        fast = fast.next.next
        temp = slow
        slow = slow.next
        temp.next = pre
        pre = temp
    
    if fast:
        slow = slow.next
    
    while slow and slow.val == pre.val:
        pre = pre.next
        slow = slow.next
    
    if not pre:
        return True
    else:
        return False
    

    核心逻辑完全一致, 但是在给一起刷题的一个大三实习生看时, 对方表示 dalao 的代码比较难懂, 反而觉得我的烂代码比较适合在工作中使用, 因为一眼就能看明白不会浪费时间.

    感觉有点迷茫在工作中应该使用什么样的代码风格了...

    30 replies  •  2020-10-09 19:27:23 +08:00
    linw1995
    linw1995
    Sep 27, 2020
    1
    对于这两段代码来说,肯定是更容易阅读的好。现在回答标题问题,两种风格并不冲突…
    chinazz
    chinazz
    Sep 27, 2020
    2
    第一种可读性也不差吧。感觉第一种读起来会更快
    Hstar
    Hstar
    Sep 27, 2020
    3
    多写写,写多了就变成第一种了
    Trim21
    Trim21
    Sep 27, 2020 via Android❤️3
    4
    前三行和最后一行感觉大佬的写法好,其他的感觉你的写法好
    loliordie
    loliordie
    OP
    Sep 27, 2020
    5
    @chinazz 实际上这个题目第四行, 由于指针移动的关系, 想根据赋值的优先级看清楚指针以及节点指向关系并不是很容易的事情, 需要先在脑内依次求出右侧三个值, 再依次赋值给三个变量. 这种做法虽然避免了中间变量, 但是增加了大脑的阅读负担...
    tcfenix
    tcfenix
    Sep 27, 2020
    6
    代码上用骚操作提升性能或者降低空间复杂度这个的确听过,
    但是想问下,城里人都是觉得降低代码量能更牛逼么?代码量越低人越厉害么?还是代码跑的更快?

    lc 本身对性能有一定的需求,在满足的前提下代码就要让人容易看懂是最有帮助的

    前一种写法限定了只写 python 的人才习惯看
    后一种写法则是对 python 基础一般或者基本上只是熟悉其他语言的读者也友好

    可能写前者代码的大佬不需要把代码给其他普通人看吧....
    mcfog
    mcfog
    Sep 27, 2020❤️3
    7
    第一种需要改进的:加空行

    第二种需要改进的:
    多赋值应该还是适当用的
    `if .. return True else return False` 这个谁这样写我头都给他打烂
    linnchord
    linnchord
    Sep 27, 2020
    8
    对比一下,流程完全一样,纯粹是语法熟悉度问题。

    你 python 熟练了,语法翻译脑力消耗低于直白手打体力消耗以后自然就变成了上面的写法,没什么神秘的。
    reus
    reus
    Sep 27, 2020 via Android
    9
    @loliordie 你应该右左右左右左地读,而不是右右右左左左
    imn1
    imn1
    Sep 27, 2020
    10
    自己写喜欢第一种,读人家的希望第二种
    哈哈,我就俗人一个

    然后
    两个月后,自己写的也没记起当时的思路是什么 😛

    结束代码块的判断,我一般只写 if,不写 else,反正 False 的情况就执行下一句也是结束,没必要再写 else
    例如,continue/break/return/exit 这些
    如果 return 一定是 True/False 二选一,我也是第一种写法
    或者说,我会在满足需求的前提下,尽快 return 结束,甚至在循环里面就 return,而不是先 break 跳出去再 return
    dustinth
    dustinth
    Sep 27, 2020
    11
    第一种代码不难懂. 唯一不好的地方是这一行:
    pre, slow.next, slow = slow, pre, slow.next
    因为这一行做了几件事情, 一行下来对读者心智负担比较重.
    aleung
    aleung
    Sep 27, 2020 via Android
    12
    第一种写法好。唯一问题是没有加空行。
    littlewing
    littlewing
    Sep 27, 2020
    13
    记住一点:代码是给人看的
    lsj8924
    lsj8924
    Sep 27, 2020
    14
    第一种看起来多快呀,你一句分三行,眼球得多 paser 多少次。
    lithbitren
    lithbitren
    Sep 27, 2020❤️1
    15
    个人愿意读第一种代码,只要效率没问题就行。

    用临时变量来实现交换对于 python 这种解释型语言来说是有效率差别的,直接元组交换视对象类型会快 20%-200%。

    如果不涉及交换,多行赋值会比单行赋值要快 20%-50%,单行赋值涉及到元组解构,如果没有交换的话应该是慢一点的,有交换的是解释器生成临时变量帮你交换,比自己声明的临时变量要快点。

    相同功能的 if 块运算以及 if-else 三元运算以及短路,从时间上几乎没有差别,怎么清晰怎么来,不过短路可以做多不止三元,多元运算的时候一般是短路比较快,但缺点就是一些布尔性质为 False 的变量不太好短路。

    利用变量的布尔性质来返回肯定比写 if 块要性能好点
    metamask
    metamask
    Sep 27, 2020
    16
    标题是有倾向性的

    pythonic 的代码风格 和 非 pythonic 的代码风格 你更倾向哪一种?
    不容易阅读的代码风格和更容易阅读的代码风格 你更倾向哪一种?

    就 python 而言,这种赋值和解包是很舒服的,没必要用 tmp 来做一个转换


    至于 三元运算,这个比较短也是可以的,
    按第二种写法,如果要说的,补多个 else,补足情况也是好的做法

    最后的判断
    if True return True 这种“容易阅读”是完全没有必要的。
    metamask
    metamask
    Sep 27, 2020
    17
    假如你从 python 角度看的话,

    第一种代码只要你肯给他加多几个空行那么是很漂亮的,
    而且用法是很简练的。
    nonduality
    nonduality
    Sep 27, 2020
    18
    喜欢第一种,不爱罗嗦、低效的写法
    Rorysky
    Rorysky
    Sep 27, 2020
    19
    没什么区别,编译器看来都是一样的
    inframe
    inframe
    Sep 27, 2020
    20
    PEP 8:
    Guido 的一个重要的见解是,代码阅读的次数比编写的次数多。这里提供的指南旨在提高代码的可读性,并使各种不同的 Python 代码一致。如 PEP20 所说,“易读性非常重要”。

    https://www.python.org/dev/peps/pep-0008/
    QingXuJiaZhi
    QingXuJiaZhi
    Sep 28, 2020
    21
    明显第一种更好,你不给人家加空行不厚道啊。
    lxilu
    lxilu
    Sep 28, 2020 via iPhone
    22
    这倒看不出 pythonic……
    NoobX
    NoobX
    Sep 28, 2020
    23
    原始代码并不属于故意缩短代码行数的类别,见过有代码为了炫技,在一行内用很多的 for 和 if-else 嵌套,个人不太推荐这么干,十分影响可读性。
    总体来说在不影响可读性的前提下,越精炼越好。相比之下,我认为你给出的原始代码更易读
    goinghugh
    goinghugh
    Sep 28, 2020
    24
    我觉得第一种好,一眼就看出要做什么了; 换个问题,写 Java 时,用 stream 还是写 for-each 比较好写易读?
    InkStone
    InkStone
    Sep 28, 2020❤️1
    25
    对于懂 Python 的人来说,第一种既更 pythonic,也更易读。

    另外赞同上面的看法,
    if not pre:
    return True
    else:
    return False
    这种写法不管在哪里都要被打死的
    cassyang
    cassyang
    Sep 28, 2020
    26
    第一个哪里不好读了。。
    component
    component
    Sep 28, 2020
    27
    @mcfog @InkStone 不懂就问,这样写有什么问题吗?是不是要用三元运算符来写?区别很大么?
    aguesuka
    aguesuka
    Sep 28, 2020 via Android
    28
    @component return not pre 。你的 ide 没有警告吗?
    laike9m
    laike9m
    Oct 2, 2020 via Android
    29
    第一个,因为它用的都是最常用的写法,没有任何花哨的地方。你觉得骚只是因为你不熟悉语法而已。
    cominghome
    cominghome
    Oct 9, 2020
    30
    pythonic 骚东西很多,这一块我了解得不多,但是第一个例子里显然都是很实用的技巧,我投第一个
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2509 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 80ms · UTC 05:02 · PVG 13:02 · LAX 21:02 · JFK 00:02
    ♥ Do have faith in what you're doing.