Элегантное назначение Python на основе значений True / False - PullRequest
28 голосов
/ 18 января 2011

У меня есть переменная, которую я хочу установить в зависимости от значений в трех логических значениях.Самый простой способ - это оператор if, за которым следует серия elifs:

if a and b and c:
    name = 'first'
elif a and b and not c:
    name = 'second'
elif a and not b and c:
    name = 'third'
elif a and not b and not c:
    name = 'fourth'
elif not a and b and c:
    name = 'fifth'
elif not a and b and not c:
    name = 'sixth'
elif not a and not b and c:
    name = 'seventh'
elif not a and not b and not c:
    name = 'eighth'

Это немного неловко, и мне интересно, есть ли более Pythonic способ справиться с этой проблемой.Несколько идей приходят на ум.

  1. Взлом словаря:

    name = {a and b and c: 'first',
            a and b and not c: 'second',
            a and not b and c: 'third',
            a and not b and not c: 'fourth',
            not a and b and c: 'fifth',
            not a and b and not c: 'sixth',
            not a and not b and c: 'seventh',
            not a and not b and not c: 'eighth'}[True]
    

Я называю это взломом, потому что я не слишком дикийоколо семи ключей ложны и перекрывают друг друга.

  1. И / или магия

    name = (a and b and c and 'first' or
            a and b and not c and 'second' or
            a and not b and c and 'third' or
            a and not b and not c and 'fourth' or
            not a and b and c and 'fifth' or
            not a and b and not c and 'sixth' or
            not a and not b and c and 'seventh' or
            not a and not b and not c and 'eighth')
    

Это работает, потому что Python ands and orsвернуть последнее значение, которое нужно оценить, но вы должны знать, что для понимания этого странного кода в противном случае.

Ни один из этих трех вариантов не является очень удовлетворительным.Что вы рекомендуете?

Ответы [ 11 ]

0 голосов
/ 18 января 2011

Я бы пошел для решения списка / битов @OscarRyz, @Clint и @Sven, но вот еще один:

<code>
S1 = frozenset(['first', 'second', 'third', 'fourth'])
S2 = frozenset(['first', 'second', 'fifth', 'sixth'])
S3 = frozenset(['first', 'third', 'fifth', 'seventh'])
last = 'eighth'
empty = frozenset([])</p>

<p>def value(a, b, c):
    for r in (a and S1 or empty) & (b and S2 or empty) & (c and S3 or empty):
        return r
    return last</p>

<p>
...