Python是否支持行内elif语句?

21
'Hello ' + ('there' if name is None else name)

是否等同于

msg = 'Hello '
if name is None:
    msg += 'there'
else:
    msg += name

这句话的等效语是什么:

msg = 'Hello '
if name is None:
    msg += 'there'
elif name == 'Mr Anderson'
    msg += 'Neo'
else:
    msg += name

编辑:以下是我想要缩小的代码的参考

srepr = '\'Modify '
if self.register == 'p':
    srepr += 'Pointer'
elif self.register == 'v':
    srepr += 'Value'
else
    srepr += 'Unknown'
srepr += ' By ' + str(self.delta) + '\''

4
srepr+={'p': 'Pointer', 'v': 'Value'}.get(self.register,'Unknown') - Kabie
7个回答

34
msg = "Hi " + ("there" if not name else ("Neo" if name == "Anderson" else name))

我认为那相当难以阅读。


1
你使用了不必要的括号,这使得代码可读性降低。请查看我的答案以获得更清晰的解决方案。 - Glenn Maynard
4
@glenn. 我加上了括号,以便更易读,但我想这是主观的。无论如何,我认为我们都同意,任何人都不应该写类似于"nothing similar"的东西。 - tokland
好的回答 - 但如果我在生产代码库中看到这个,那我会度过漫长的一天。 :P - alex

8
使用字典进行映射:
srepr = "'Modify " + {"p": "Pointer", "v": "value"}.get(self.register, "Unknown")

顺便提一下,为了更加清晰,您可以使用"'...代替'\'...'


6
msg = 'Hello ' + (
    'there' if name is None else
    'Neo' if name == 'Mr Anderson' else
    name
)

这是对其他答案的重申,但具有更好的格式。我认为这是最易读的方法,这也是我会使用的方法。


3
'Hello ' + \
('there' if name is None else \
    'Neo' if name == 'Mr Anderson' else \
    name)

我建议不要这样做;如果你的条件变得这么复杂,就把它放在一个函数里。


这是我会采用的方法,但按照这里所写的方式,格式化非常嘈杂。请参阅我的答案,了解一个没有反斜杠和具有一致缩进的版本。 - maackle

2

不要这样做。

改为这样做:

% python -m this | sed 's/^R.*/======>&<======/'

编辑:供参考,以下是我会如何重构这段代码...

每当我看到elif时,我就想到dict

#!/usr/bin/env python

class Shrink(object):
    types = {
            'p': 'Pointer',
            'v': 'Value',
            }

    def shrink_this(self):
        return "'Modify %s By %s'" % (
                self.types.get(self.register, 'Unknown'), self.delta)

import unittest
class TestShrink(unittest.TestCase):

    def test_p(self):
        s = Shrink();
        s.register = 'p'
        s.delta = 'delta'
        self.assertEquals("'Modify Pointer By delta'", s.shrink_this())

    def test_u(self):
        s = Shrink();
        s.register = 'u'
        s.delta = 'echo'
        self.assertEquals("'Modify Unknown By echo'", s.shrink_this())

    def test_v(self):
        s = Shrink();
        s.register = 'v'
        s.delta = 'foxtrot'
        self.assertEquals("'Modify Value By foxtrot'", s.shrink_this())

if __name__ == '__main__':
    unittest.main()

如果你需要添加r代表引用或者pp代表指向指针的指针,只有types需要更改,你的代码仍然易读。

易读性至关重要。


2
哎呀,为什么要踩我呢?“Python之禅”对于任何Python程序员来说都是重要的阅读材料(连同PEP008一起)。sed命令强调了这一点。 - johnsyweb
1
问题中提到了Python 3.x。使用return "'Modify {} By {}'".format(self.types.get(self.register, 'Unknown'), self.delta) - Duncan
另外一个投反对票的建议是:“如果您看到错误信息,请投反对票。添加评论指出具体错误之处。提供您自己更好的答案。最好的方法是编辑和改进现有的问题和答案!”。--《诚实待人,SO FAQhttp://stackoverflow.com/faq》 - johnsyweb

0

你也可以这样做:

msg= 'Hello ' + {name is None: 'there', name == 'Mr Anderson': 'Neo'}.get(True, name)

所以,如果name is None或者name == 'Mr Anderson'其中之一是True,或者两者都不是True,那么name将被使用。


-2
首先,运行命令 'pip install pyswitch'。
然后:
import pyswitch

mySwitch = pyswitch.Switch()

@mySwitch.case(None):
def gotNone(value):
    return 'Hello there'

@mySwitch.case('Mr. Anderson')
def gotMrAnderson(value):
    return 'Hello Neo'

@mySwitch.default
def gotDefault(value):
    return 'Hello %s' % value

msg = mySwitch.switch(None)  # Returns 'Hello there'
msg = mySwitch.switch('Mr. Anderson')  # Returns 'Hello Neo'
msg = mySwitch.switch('OoglyMoogly')  # Returns 'Hello OoglyMoogly'

1
随着你的'elif'链的长度增加,这个解决方案的吸引力也会增加。它基本上就像是Python语言中的C语言switch语句。请参见http://pypi.python.org/pypi?%3Aaction=search&term=pyswitch&submit=search。 - Michael Kent
如果必要的话,可以使用一个以情况为键、可能是lambda函数的值的字典。即使在大语句中,这种方式比pyswitch简单得多。 - aliqandil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接