ファイルから読み取ったTrue / False値をブール値に変換します


88

True - Falseファイルから値を読み取っていますが、ブール値に変換する必要があります。現在True、値がに設定されている場合でも、常にに変換されFalseます。

ここだMWE、私が何をしようとしているのは:

with open('file.dat', mode="r") as f:
    for line in f:
        reader = line.split()
        # Convert to boolean <-- Not working?
        flag = bool(reader[0])

if flag:
    print 'flag == True'
else:
    print 'flag == False'

このfile.datファイルは基本的に、値TrueまたはFalse内部に書き込まれた単一の文字列で構成されます。これははるかに大きなコードからの最小限の例であり、これがパラメーターを読み取る方法であるため、配置は非常に複雑に見えます。

なぜflag常にに変換するのTrueですか?


1
pip install str2bool
Symon

回答:


101

bool('True')文字列「True」と「False」は空ではないため、bool('False')常に戻りTrueます。

偉大な人(およびPythonのドキュメント)を引用するには:

5.1。真理値テスト

ifまたはwhile条件で使用するため、または以下のブール演算のオペランドとして使用するために、任意のオブジェクトの真理値をテストできます。次の値はfalseと見なされます。

  • 例えば、任意の数値型のゼロ、00L0.00j
  • 例えば、任意の空のシーケンス、''()[]

他のすべての値はtrueと見なされるため、多くのタイプのオブジェクトは常にtrueです。

組み込みbool関数は、標準の真理テスト手順を使用します。だからあなたはいつも得ているのTrueです。

文字列をブール値に変換するには、次のようなことを行う必要があります。

def str_to_bool(s):
    if s == 'True':
         return True
    elif s == 'False':
         return False
    else:
         raise ValueError # evil ValueError that doesn't tell you what the wrong value was

24
あなたはそれを「英雄」作ることができますValueError行うことでraise ValueError("Cannot covert {} to a bool".format(s))
SethMMorton 2014

追加のパッケージを使用しないため、これを選択します。みんなありがとう!
ガブリエル

1
「追加パッケージ」の何が問題になっていますか?あなたは言及していastますか?これは標準ライブラリの一部なので、それほど余分なものではありません。
SethMMorton 2014

4
それは愚かな質問かもしれませんが、なぜないboolだけで文字列を変換しないTrueFalseブール値へTrueFalse?何をするかから一貫性のない動作のようintです。なぜ私の推論が間違っているのか、そしてなぜ他の選択肢が決定だったのか、私は本当に興味があります。
チャーリーパーカー

1
文字列を比較するときはいつでも、ケースを平らにするのが好きです(該当する場合)。たとえば、次のように使用します。ifs.upper()== 'TRUE':return True elif s.upper()== 'FALSE' return False
Bill Kidd

75

あなたが使用することができます distutils.util.strtobool

>>> from distutils.util import strtobool

>>> strtobool('True')
1
>>> strtobool('False')
0

True値でありyyesttrueon1False値はnnoffalseoff0。発生させValueErrorた場合valが何かです。


23
さらに良いことbool(strtobool(my_string))に、出力をブール値のTrue / False変数としてキャストする
AlexG 2017年

11
@AlexGstrtobool()は、呼び出された関数が実際にはbool
derickeを

61

使用ast.literal_eval

>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False

フラグが常にTrueに変換されるのはなぜですか?

空でない文字列は、Pythonでは常にTrueです。

関連:真理値テスト


NumPyがオプションの場合、次のようになります。

>>> import StringIO
>>> import numpy as np
>>> s = 'True - False - True'
>>> c = StringIO.StringIO(s)
>>> np.genfromtxt(c, delimiter='-', autostrip=True, dtype=None) #or dtype=bool
array([ True, False,  True], dtype=bool)

それは愚かな質問かもしれませんが、なぜないboolだけで文字列を変換しないTrueFalseブール値へTrueFalse?何をするかから一貫性のない動作のようintです。なぜ私の推論が間違っているのか、そしてなぜ他の選択肢が決定だったのか、私は本当に興味があります。
チャーリーパーカー

2
ast.literal_eval( 'false')は例外をスローしますが、これはあまり望ましくないと思います
Chris

@Chrisいつでもtryをラップすることができます-直接使用する代わりにカスタム関数を除きます。
Ashwini Chaudhary 2018

@HewwoCrazinessランダムなコードではなく、式のみを解析します。
AshwiniChaudhary19年

16

私が見た中で最もクリーンな解決策は次のとおりです。

from distutils.util import strtobool
def string_to_bool(string):
    return bool(strtobool(str(string)))

確かに、インポートが必要ですが、適切なエラー処理があり、記述(およびテスト)するコードはほとんど必要ありません。


入力値が実際にブール値である場合を除いて、これは機能しません。そうでない場合、値エラーをスローするようです。私が考えることができる唯一のことは、関数にtry / exceptionを追加し、ValueErrorfalseを返すことです。
アリ

13

これを最良の答えとして提案するのではなく、単なる代替手段ですが、次のようなこともできます。

flag = reader[0] == "True"

フラグはTrueidreader [0]は「True」になり、それ以外の場合はFalse。になります。


10

現在、True変数に値があるため、評価中です。あり、ここで見つかった良い例が、あなたがbooleanとして、任意の種類を評価するときに何が起こるかと。

つまり、実行したいのは、'True'または'False'文字列を分離して実行evalすることです。

>>> eval('True')
True
>>> eval('False')
False

4
@samyievalメソッドを使用するのは危険です。stackoverflow.com/questions/1832940/…–
M07

1
ご参考までに。これはひどい考えであり、決して使用しないでくださいeval()。私の意見では、それは言語から削除されるべきです。
Nostalg.io 2018

これはセキュリティ上の欠陥であるため、非常に悪いです。eval()ファイルの生データを使用する場合、そのファイルへの書き込みアクセス権を持つすべてのユーザーが、スクリプトと同じアクセス許可レベルでコードを実行できることを意味します。
キース・リプリー

さらに、値に正確なPythonスペルがない場合、たとえばeval('false')eval('FALSE')エラーが発生します。
kev 2018

5

dictを使用して、文字列をブール値に変換できます。この行flag = bool(reader[0])を次のように変更します。

flag = {'True': True, 'False': False}.get(reader[0], False) # default is False

5

大文字と小文字を区別したくない場合は、次のようにすることができます。

b = True if bool_str.lower() == 'true' else False

使用例:

>>> bool_str = 'False'
>>> b = True if bool_str.lower() == 'true' else False
>>> b
False
>>> bool_str = 'true'
>>> b = True if bool_str.lower() == 'true' else False
>>> b
True


2

あなたはで行うことができますjson

In [124]: import json

In [125]: json.loads('false')
Out[125]: False

In [126]: json.loads('true')
Out[126]: True

2

真理値が変化する可能性がある場合、たとえば、異なるプログラミング言語または異なるタイプからの入力である場合、より堅牢な方法は次のようになります。

flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support

そして、よりパフォーマンスの高いバリアントは次のようになります(セットルックアップはO(1)です):

TRUTHS = set(['True','true',1,'T','t','1'])
flag = value in truths


0

文字列をbool(ほとんどの文字列で機能する)に変換する簡単な方法が必要な場合は、試してみてください。

def conv2bool(arg):
   try:
     res= (arg[0].upper()) == "T"
   except Exception,e:
     res= False
   return res # or do some more processing with arg if res is false


0

dictを使用して「True」をTrueに変換します。

def str_to_bool(s: str):
    status = {"True": True,
                "False": False}
    try:
        return status[s]
    except KeyError as e:
        #logging
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.