Odczytuję True - False
wartość z pliku i muszę przekonwertować ją na wartość logiczną. Obecnie zawsze konwertuje ją na, True
nawet jeśli wartość jest ustawiona na False
.
Oto, MWE
co próbuję zrobić:
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
Plik w zasadzie składa się z pojedynczego sznurka z wartością True
lub False
pisemnej wewnątrz. Aranżacja wygląda na bardzo zawiłą, ponieważ jest to minimalny przykład ze znacznie większego kodu i tak właśnie wczytuję do niego parametry.
Dlaczego flag
zawsze przechodzi na True
?
Odpowiedzi:
bool('True')
ibool('False')
zawsze zwracają,True
ponieważ ciągi „True” i „False” nie są puste.Cytując wspaniałego człowieka (i dokumentację Pythona ):
Funkcja wbudowana
bool
korzysta ze standardowej procedury sprawdzania prawdy. Dlatego zawsze dostajeszTrue
.Aby przekonwertować ciąg na boolean, musisz zrobić coś takiego:
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
źródło
ValueError
Robiąc to, możesz uczynić to „bohaterskim”raise ValueError("Cannot covert {} to a bool".format(s))
.ast
? Jest częścią standardowej biblioteki, więc nie jest tak naprawdę dodatkowa.bool
po prostu nie konwertuje ciągów znakówTrue
iFalse
na wartości logiczneTrue
iFalse
? Wydaje się, że zachowanie jest niespójne w porównaniu z tym, co sięint
dzieje. Jestem po prostu naprawdę ciekawy, dlaczego moje rozumowanie jest błędne i dlaczego inna opcja była tą decyzją.możesz użyć
distutils.util.strtobool
>>> from distutils.util import strtobool >>> strtobool('True') 1 >>> strtobool('False') 0
True
wartościy
,yes
,t
,true
,on
i1
;False
wartościn
,no
,f
,false
,off
i0
. Podnosi się,ValueError
jeśli val jest czymś innym.źródło
bool(strtobool(my_string))
rzutowanie wyjścia jako zmiennej typu boolean True / Falsestrtobool()
w rzeczywistości nie zwraca abool
Zastosowanie
ast.literal_eval
:>>> import ast >>> ast.literal_eval('True') True >>> ast.literal_eval('False') False
Niepuste łańcuchy są zawsze True w Pythonie.
Powiązane: Testowanie wartości prawdy
Jeśli NumPy jest opcją, to:
>>> 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)
źródło
bool
po prostu nie konwertuje ciągów znakówTrue
iFalse
na wartości logiczneTrue
iFalse
? Wydaje się, że zachowanie jest niespójne w porównaniu z tym, co sięint
dzieje. Jestem po prostu naprawdę ciekawy, dlaczego moje rozumowanie jest błędne i dlaczego inna opcja była tą decyzją.Najczystszym rozwiązaniem, jakie widziałem, jest:
from distutils.util import strtobool def string_to_bool(string): return bool(strtobool(str(string)))
Oczywiście, wymaga importu, ale ma odpowiednią obsługę błędów i wymaga bardzo niewielkiej ilości kodu do napisania (i przetestowania).
źródło
Nie sugeruję, że to najlepsza odpowiedź, tylko alternatywa, ale możesz też zrobić coś takiego:
flag = reader[0] == "True"
flaga będzie miała wartość
True
ID czytnika [0] ma wartość „True”, w przeciwnym razie będzieFalse
.źródło
Obecnie jest oceniany do,
True
ponieważ zmienna ma wartość. Znajduje się tutaj dobry przykład tego, co się dzieje, gdy oceniasz dowolne typy jako wartości logiczne.Krótko mówiąc, to, co chcesz zrobić, to wyizolować ciąg
'True'
lub'False'
i uruchomićeval
na nim.>>> eval('True') True >>> eval('False') False
źródło
eval()
. Moim zdaniem należy go usunąć z języka.eval()
surowych danych z pliku, oznacza to, że każdy, kto ma prawo do zapisu w tym pliku, może wykonywać kod na tym samym poziomie uprawnień, co twój skrypt.eval('false')
,eval('FALSE')
będzie to błąd.Możesz użyć dict, aby przekonwertować ciąg znaków na wartość logiczną. Zmień tę linię
flag = bool(reader[0])
na:flag = {'True': True, 'False': False}.get(reader[0], False) # default is False
źródło
Jeśli chcesz nie rozróżniać wielkości liter, możesz po prostu:
b = True if bool_str.lower() == 'true' else False
Przykładowe użycie:
>>> 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
źródło
pip zainstaluj str2bool
>>> from str2bool import str2bool >>> str2bool('Yes') True >>> str2bool('FaLsE') False
źródło
Możesz zrobić z
json
.In [124]: import json In [125]: json.loads('false') Out[125]: False In [126]: json.loads('true') Out[126]: True
źródło
Wystarczy dodać, że jeśli wartość prawdy może się różnić, na przykład jeśli jest to dane wejściowe z różnych języków programowania lub z różnych typów, bardziej niezawodną metodą byłoby:
flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support
Bardziej wydajnym wariantem byłby (wyszukiwanie zestawu to O (1)):
TRUTHS = set(['True','true',1,'T','t','1']) flag = value in truths
źródło
Jeśli Twoje dane pochodzą z json, możesz to zrobić
źródło
Jeśli potrzebujesz szybkiego sposobu na konwersję ciągów znaków na boole (które działają z większością łańcuchów), spróbuj.
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
źródło
Używanie dykt do konwersji „True” na True:
def str_to_bool(s: str): status = {"True": True, "False": False} try: return status[s] except KeyError as e: #logging
źródło