web-dev-qa-db-ja.com

boolsをintとして使用するのはPythonicですか?

False0と同等であり、True1と同等であるため、次のようなことが可能です。

def bool_to_str(value):
    """value should be a bool"""
    return ['No', 'Yes'][value]

bool_to_str(True)

値がboolであるが、intとして使用されていることに注意してください。

これはPythonicのこの種の使用ですか、それとも避けるべきですか?

67
hwiechers

私は奇妙な声になります(言語が保証するように、すべての答えが_False == 0_と_True == 1_という事実の使用を非難しているので)私はこの事実を使用してコードを単純化すると主張します完全に大丈夫です。

歴史的に、論理的なtrue/false操作は、falseの場合は_0_を使用し、trueの場合は_1_を使用する傾向がありました。 Python 2.2のライフサイクルの過程で、Guidoは、_false = 0; true = 1_などの割り当てで開始されたモジュールが多すぎることに気付き、これにより定型的で役に立たないバリエーションが生成されました(後者は大文字化のためtrueとfalseがいたるところにあり、一部はすべて大文字、一部はすべて小文字、一部は大文字のイニシャル)であるため、boolintサブクラスとそのTrueおよびFalse定数が導入されました。

私たちの多くは、新しい型と定数が言語のPython初心者がrestrictに使用されるのではないかと恐れていたため、当時はかなりの反発がありました。 Guidoは、私たちが悲観的であると断言しました。たとえば、リストインデックスとしてのFalseTrueの完全に自然な使用を回避するほど、Pythonをひどく理解する人は、誰もいません。総和、または他のそのような完全に明確で有用なイディオム。

このスレッドへの答えは、私たちが正しかったことを証明しています。恐れていたように、このタイプと定数の役割についての完全な誤解が現れ、人々回避し、さらに悪いことに、他の人に回避するように促し、完全に自然なPythonは、役に立たない回転を支持する構造になります。

そのような誤解の流れと戦って、私は皆にPython as Pythonnotそれを強制しようとする)を使用することを勧めます機能性と好みのスタイルがまったく異なる他の言語の型にPythonの場合、TrueとFalseは1と0のように99.9%で、排他的に異なりますstr(...)(したがってrepr(...))形式で-文字列化以外のすべての他の操作については、ゆがみなく自由に使用してください。これは、インデックス作成、算術演算、ビット演算などに当てはまります。

161
Alex Martelli

私はアレックスと一緒です。 _False==0_と_True==1_、そしてそれは何も悪いことではありません。

それでも、Python 2.5以降では、Pythonの条件式を使用してこの特定の質問に対する答えを記述します。

_def bool_to_str(value):
  return 'Yes' if value else 'No'
_

そうすれば、引数が実際にブール値である必要はありません-_if x: ..._がxの任意の型を受け入れるように、bool_to_str()関数は渡されたときに正しいことを行う必要がありますなし、文字列、リスト、または3.14。

144

確かに:

def bool_to_str(value):
    "value should be a bool"
    return 'Yes' if value else 'No'

より読みやすくなります。

37
SilentGhost

場合によっては、コードが不正確に見えることがあります。

>>> def bool_to_str(value):
...     """value should be a bool"""
...     return ['No', 'Yes'][value]
...
>>> bool_to_str(-2)
'No'

また、読みやすくするために条件演算子のみを使用することをお勧めします。

def bool_to_str(value):
    """value should be a bool"""
    return "Yes" if value else "No"
13
minhee

False == 0およびTrue == 1(実装に依存しません): False == 0およびTrue == 1 in Python実装の詳細ですか、それとも言語によって保証されていますか?

ただし、他のほとんどの回答には同意します。['No', 'Yes'][value]または辞書を使用して、… if value else …と同じ結果を取得するためのより読みやすい方法があり、それぞれに次の利点があります。 valueがブール値であることをほのめかして述べます。

さらに、… if value else …は、非0がTrueであるという通常の規則に従います。これは、dahliaが示唆するように、value == -2(値がTrue)の場合でも機能します。この場合、listとdictのアプローチはそれほど堅牢ではないため、お勧めしません。

5
Eric O Lebigot

Boolはintのサブクラスであるため、boolをintとして使用しても問題ありません。

>>> isinstance(True, int)
True
>>> isinstance(False, int)
True

あなたのコードについて:そのような1行の関数にそれを置くことは上にあります。読者は関数のソースまたはドキュメントを見つけて読む必要があります(関数の名前からはあまりわかりません)。これにより、フローが中断されます。インラインに配置し、リスト(実行時に作成)を使用せず、タプル(値が定数の場合はコンパイル時に作成)を使用します。例:

print foo, bar, num_things, ("OK", "Too many!)[num_things > max_things]
1
John Machin

個人的には、この事実をどのように使用したいかによると思います。ここに2つの例があります。

  1. 条件文で問題ないので、単にブール値を使用してください。人々はいつもこれをします。

    a = 0
    if a:
        do something
    
  2. ただし、成功したアイテムの数を数えたいとすると、コードは他の人が読むのにあまり友好的ではない可能性があります。

    def succeed(val):
        if do_something(val):
            return True
        else:
            return False
    
    count = 0
    values = [some values to process]
    for val in values:
        count += succeed(val)
    

しかし、本番コードは次のようになっています。

all_successful = all([succeed(val) for val in values])
at_least_one_successful = any([succeed(val) for val in values])
total_number_of_successful = sum([succeed(val) for val in values])
0
user7135792