Konwertujesz ciąg znaków na wartość logiczną w Pythonie?


745

Czy ktoś wie, jak wykonać konwersję z ciągu znaków na wartość logiczną w Pythonie? Znalazłem ten link . Ale to nie wygląda na właściwy sposób. Tj. Przy użyciu wbudowanej funkcjonalności itp.

Pytam o to, ponieważ dowiedziałem się o tym int("string")stąd. Ale podczas próby bool("string")zawsze zwraca True:

>>> bool("False")
True

2
właśnie dla tego stworzyłem mikro-bibliotekę, która zawiera także obce słowa, np. „tak” dla języka polskiego, „是 的” w języku mandaryńskim-chińskim będzie miało wartość True . Jeśli nie jest to jawnie prawdziwe, wartość będzie fałszywa . Sugestie są mile widziane. Link do Github: github.com/kmonsoor/str2bool
kmonsoor

18
Zamiast wymyślać na nowo koło i pisać wiele kodów, które musisz przeładować, odpowiedź @ jzwiener korzysta z funkcji ze standardowej biblioteki Pythonadistutils.util.strtobool(some_string) . Technicznie dane wyjściowe są typu intz wartością 0lub 1-> jeśli naprawdę chcesz / potrzebujesz bool, możesz owinąć tę funkcję bool(distutils.util.strtobool(some_string)).
Trevor Boyd Smith

1
pip install str2bool
Symon

Tylko jedna głowa do góry. distutils.util.strtoboolnie może obsłużyć zagranicznych tak / nie, w odróżnieniu od roztworu przez @kmonsoor, który jednak nie może obsłużyć pliki CSV Excel wykonane z prawda / fałsz w języku obcym (np VERO, FALSO). Dlatego czasami wymagane jest wynalezienie koła.
Matteo Ferla

Odpowiedzi:


837

Naprawdę po prostu porównujesz ciąg znaków z tym, co spodziewasz się zaakceptować jako reprezentujące prawdę, więc możesz to zrobić:

s == 'True'

Lub w celu sprawdzenia całej gamy wartości:

s.lower() in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh']

Zachowaj ostrożność podczas korzystania z następujących opcji:

>>> bool("foo")
True
>>> bool("")
False

Puste ciągi wartości do False, ale wszystko inne do wartości True. Dlatego nie należy tego używać do jakichkolwiek celów analizy.


48
+1: niewiele może być prostsze niż s == "True". Ale widziałem, jak ludzie robią z tego prawdziwy bałagan. def convert (s): if s == "True": return True; zwrócić False.
S.Lott,

24
Wolę zwrot s == „True” niż if / else
Dana

26
if s == "True": return True elif s == "False": return False else: return raise
Nieznany

9
Parsowanie ciągów znaków na booleany jest już zaimplementowane w distutils.util.strtobool: stackoverflow.com/a/18472142/923599
jzwiener

9
Wiem, że to NAPRAWDĘ stary temat, ale chciałem potwierdzić, że spędziłem 4 godziny próbując debugować mój kod. Mój błąd próbował rzucić bool("False"). Zawsze będzie przesyłane do True.
Ev.

304

Posługiwać się:

bool(distutils.util.strtobool(some_string))

Prawdziwe wartości to y, tak, t, prawda, on i 1; fałszywe wartości to n, no, f, false, off i 0. Podnosi wartośćError, jeśli val jest czymś innym.

Należy pamiętać, że distutils.util.strtobool()zwraca reprezentacje liczb całkowitych, dlatego należy je zapakować, bool()aby uzyskać wartości logiczne.


38
Niestety to zwraca 1/ 0nie True/ False, więc musisz zawinąć wynik w bool (), aby uzyskać rzeczywistą wartość logiczną:bool(distutils.util.strtobool(some_string))
Mariusz Jamro

2
Ta funkcja jest kusząca. Byłoby idealnie, gdyby obsługiwał liczby całkowite Nonei str(None)jako dane wejściowe.
MarkHu,

20
Wolę to od wyżej głosowanych odpowiedzi ... pochodzi ze stdlib i robi dokładnie to, co jest wymagane. Zasadniczo nie ma powodu, aby potrzebować faktycznego boolzamiast 1/ 0o ile nie robisz złych rzeczy, takich jak if x == False... a jeśli masz do czynienia z intsi i Nonenie potrzebujesz specjalnej funkcji, możesz po prostu je sprawdzić bezpośrednio if myint:lubif not maybe_none_var:
Anentropic

4
@Secator booljest podklasąint
Anentropic

1
Aby ocalić komuś błędy w Google: importuj distutils i importuj distutils.util, aby to zadziałało.
Edward B.

267
def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")

Nazwij to tak:

>>> str2bool("yes")
True
>>> str2bool("no")
False
>>> str2bool("stuff")
False
>>> str2bool("1")
True
>>> str2bool("0")
False

Obsługa prawdy i fałszu w sposób jawny:

Możesz także sprawić, aby funkcja jawnie sprawdzała z prawdziwą listą słów i fałszywą listą słów. Następnie, jeśli nie ma jej na żadnej liście, możesz zgłosić wyjątek.


29
Niewielkie ulepszenie można wprowadzić za pomocą, str (v) .lower () zamiast v.lower () . Wtedy może działać, nawet jeśli nie jest sznurkiem, np. 1, 0
kmonsoor

RE: jawnie obsługując wartość prawda / fałsz, możesz również podać wartość domyślną, jeśli łańcuch nie jest dopasowany, podobnie jak działają monity wiersza polecenia prawda / fałsz: Kontynuować? (r / N)
Johnus

113

Parser JSON jest również przydatny do ogólnej konwersji ciągów znaków na rozsądne typy python.

>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True

31
Uwaga: ta metoda działa tylko wtedy, gdy jest pisana małymi literami. Jeśli to wielkie litery, nie możesz. Musisz zadzwonić.lower()
CppLearner

107

Począwszy od Python 2.6, teraz jest ast.literal_eval:

>>> import ast
>>> pomoc (ast.literal_eval)
Pomoc na temat funkcji literal_eval w module ast:

literal_eval (node_or_string)
    Bezpiecznie oceń węzeł wyrażenia lub ciąg znaków zawierający Python
    wyrażenie. Podany ciąg lub węzeł może składać się tylko z następujących elementów
    Struktury dosłowne w języku Python: ciągi, liczby, krotki, listy, dykta, booleany,
    i brak.

Który wydaje się działać tak długo, jak jesteś pewien struny zamiar być "True"albo "False":

>>> ast.literal_eval („True”)
Prawdziwe
>>> ast.literal_eval („False”)
Fałszywe
>>> ast.literal_eval („F”)
Traceback (ostatnie połączenie ostatnio):
  Plik „”, wiersz 1, w 
  Plik „/opt/Python-2.6.1/lib/python2.6/ast.py”, wiersz 68, w literale_eval
    return _convert (node_or_string)
  Plik „/opt/Python-2.6.1/lib/python2.6/ast.py”, wiersz 67, w _convert
    raise ValueError („źle sformułowany ciąg”)
ValueError: źle sformułowany ciąg
>>> ast.literal_eval („„ False ””)
'Fałszywe'

Zwykle nie polecałbym tego, ale jest on całkowicie wbudowany i może być właściwy w zależności od twoich wymagań.


1
Nie jestem pewien ogólnej możliwości zastosowania tego rozwiązania, ale ogólnie jest to bardzo miłe. +1!
SingleNegationElimination

3
Gaah, to przerażające! Potem znowu, to nie znaczy, że nie jest to zalecane, a nie odpowiedź na pytanie zgrabnie. Dobre znalezisko!
Vanessa Phipps,

4
Niestety nie obsługuje tego przypadku >>> ast.literal_eval („true”) lub ast.literal_eval („TRUE”) Podnosi >>> podwyższenie ValueError („źle sformułowany ciąg”) Poprawka jest prosta, choć ast.literal_eval (to_test .title ())
Bhushan

Nie jest to świetne rozwiązanie dla tego konkretnego pytania, ale ... Wow, dosłownie: jest cholernie przydatne! Łańcuch do listy, dict, ect.
travc

Czy to działa na Unicode? W moim widoku Django mam wartość przychodzącą, którą chcę zmienić na wartość logiczną, podając wyjątek w postaci źle sformułowanego ciągu.
Prakhar Mohan Srivastava

48

Jeśli wiesz, że ciąg będzie albo "True"albo "False", możesz po prostu użyć eval(s).

>>> eval("True")
True
>>> eval("False")
False

Używaj tego tylko wtedy, gdy masz pewność co do zawartości łańcucha, ponieważ spowoduje to wyjątek, jeśli łańcuch nie zawiera prawidłowego języka Python, a także wykona kod zawarty w łańcuchu.


5
ten łańcuch skądś przyjdzie. if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
nurettin

4
@nurettin, stąd mój komentarz na temat używania go tylko wtedy, gdy jesteś pewien zawartości łańcucha.
Joel Croteau

17

Ta wersja zachowuje semantykę konstruktorów, takich jak int (wartość) i zapewnia łatwy sposób definiowania akceptowalnych wartości ciągu.

def to_bool(value):
    valid = {'true': True, 't': True, '1': True,
             'false': False, 'f': False, '0': False,
             }   

    if isinstance(value, bool):
        return value

    if not isinstance(value, basestring):
        raise ValueError('invalid literal for boolean. Not a string.')

    lower_value = value.lower()
    if lower_value in valid:
        return valid[lower_value]
    else:
        raise ValueError('invalid literal for boolean: "%s"' % value)


# Test cases
assert to_bool('true'), '"true" is True' 
assert to_bool('True'), '"True" is True' 
assert to_bool('TRue'), '"TRue" is True' 
assert to_bool('TRUE'), '"TRUE" is True' 
assert to_bool('T'), '"T" is True' 
assert to_bool('t'), '"t" is True' 
assert to_bool('1'), '"1" is True' 
assert to_bool(True), 'True is True' 
assert to_bool(u'true'), 'unicode "true" is True'

assert to_bool('false') is False, '"false" is False' 
assert to_bool('False') is False, '"False" is False' 
assert to_bool('FAlse') is False, '"FAlse" is False' 
assert to_bool('FALSE') is False, '"FALSE" is False' 
assert to_bool('F') is False, '"F" is False' 
assert to_bool('f') is False, '"f" is False' 
assert to_bool('0') is False, '"0" is False' 
assert to_bool(False) is False, 'False is False'
assert to_bool(u'false') is False, 'unicode "false" is False'

# Expect ValueError to be raised for invalid parameter...
try:
    to_bool('')
    to_bool(12)
    to_bool([])
    to_bool('yes')
    to_bool('FOObar')
except ValueError, e:
    pass

3
Nit: Twój ostatni „przypadek testowy” spowoduje błąd przy pierwszym wywołaniu i nie przetestuje pozostałych. Nie zawiedzie również, jeśli błąd nie zostanie zgłoszony.
sierpień

12

Oto moja wersja. Sprawdza zarówno listy wartości dodatnich, jak i ujemnych, zgłaszając wyjątek dla nieznanych wartości. I nie otrzymuje ciągu, ale każdy typ powinien.

def to_bool(value):
    """
       Converts 'something' to boolean. Raises exception for invalid formats
           Possible True  values: 1, True, "1", "TRue", "yes", "y", "t"
           Possible False values: 0, False, None, [], {}, "", "0", "faLse", "no", "n", "f", 0.0, ...
    """
    if str(value).lower() in ("yes", "y", "true",  "t", "1"): return True
    if str(value).lower() in ("no",  "n", "false", "f", "0", "0.0", "", "none", "[]", "{}"): return False
    raise Exception('Invalid value for boolean conversion: ' + str(value))

Przykładowe przebiegi:

>>> to_bool(True)
True
>>> to_bool("tRUe")
True
>>> to_bool("1")
True
>>> to_bool(1)
True
>>> to_bool(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: 2
>>> to_bool([])
False
>>> to_bool({})
False
>>> to_bool(None)
False
>>> to_bool("Wasssaaaaa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: Wasssaaaaa
>>>

Można się tym ugryźć: to to_bool(["hello"])powinno być całkowicie poprawne połączenie, jeśli []jest obsługiwane
Rafael T

1
Zwraca „Wyjątek: niepoprawna wartość konwersji boolowskiej: [„ hello ”]”, która jest oczekiwana i udokumentowana. Moim zdaniem pusta lista była wyraźnie fałszem, ale [„fałsz”] nie był wyraźnie niczym, więc celowo ją pominąłem - to funkcja, a nie błąd. Powinno być łatwo dodać obsługę zwracania wartości true dla niepustych list, jeśli tego chcesz.
Petrucio,

1
pewnie to udokumentowałeś. Ale w prawdziwym życiu nikt nie zadzwoniłby to_bool([]). Zamiast tego zrobiłby coś w tym stylu: myList=someFunctionThatReturnAList`if (is_bool (myList)): ... so więc ktoś ma listę i chce wiedzieć, czy ta lista jest Brak, czy pusta.
Rafael T

Dlaczego nie spróbować: >>> def a2b (arg): ... default = bool (arg) ... if isinstance (arg, str): ... return arg.lower () in ['true', ' t ',' yes ',' y ',' 1 '] ... else: ... return default
ThePracticalOne

5
Drobny punkt: prawdopodobnie powinieneś preferować ValueError niż zwykły wyjątek.
dshepherd,

10

zawsze możesz zrobić coś takiego

myString = "false"
val = (myString == "true")

bit w parens miałby wartość False. To tylko kolejny sposób na zrobienie tego bez konieczności wykonywania rzeczywistego wywołania funkcji.


1
Co val = "false"robi linia na tym przykładzie? Dlaczego tam jest Co to znaczy?
S.Lott,

9
Myślę, że to oznacza 42.
Geo

@Geo: Zgadzam się; ale na jakie pytanie odpowiedziano w tym stwierdzeniu?
S.Lott,

właśnie tego szukałem, oceniając pole wejściowe z pliku i opierając się na wyniku przechowywania wartości logicznej. Dziękuję Ci.
jimh

9

Fajna, prosta sztuczka (na podstawie tego, co napisał @Alan Marchiori), ale przy użyciu yaml:

import yaml

parsed = yaml.load("true")
print bool(parsed)

Jeśli jest zbyt szeroki, można go ulepszyć, testując wynik typu. Jeśli typ zwracany przez yaml jest str, to nie można go rzutować na żaden inny typ (który i tak mogę wymyślić), więc możesz sobie z tym poradzić osobno lub po prostu pozwolić, by to była prawda.

Nie będę zgadywał z dużą szybkością, ale ponieważ i tak pracuję z danymi yaml pod Qt gui, ma to niezłą symetrię.


1
yamlModuł jest biblioteką osoba trzecia: PyYAML
Peter Wood

8

Nie zgadzam się z żadnym rozwiązaniem tutaj, ponieważ są zbyt liberalne. Zwykle nie jest to pożądane podczas analizowania łańcucha.

Więc tutaj używam rozwiązania:

def to_bool(bool_str):
    """Parse the string and return the boolean value encoded or raise an exception"""
    if isinstance(bool_str, basestring) and bool_str: 
        if bool_str.lower() in ['true', 't', '1']: return True
        elif bool_str.lower() in ['false', 'f', '0']: return False

    #if here we couldn't parse it
    raise ValueError("%s is no recognized as a boolean value" % bool_str)

A wyniki:

>>> [to_bool(v) for v in ['true','t','1','F','FALSE','0']]
[True, True, True, False, False, False]
>>> to_bool("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in to_bool
ValueError: '' is no recognized as a boolean value

Żeby było jasne, bo wygląda na to, że moja odpowiedź jakoś uraziła kogoś:

Chodzi o to, że nie chcesz testować tylko jednej wartości i zakładać drugą. Nie sądzę, żebyś zawsze chciał mapować Absolutnie wszystko na nieparsowaną wartość. To powoduje powstanie kodu podatnego na błędy.

Więc jeśli wiesz, w co chcesz to zakodować.


2
Myślę, że nie rozumiesz sedna sprawy: celem odpowiedzi było zademonstrowanie ogólnej zasady, a nie podanie osobie, która zadała pytanie, w jaki sposób powinna to zrobić. Osoba, która pierwotnie zadała pytanie, zastanowiła się nad tym, co tak naprawdę jest prostym problemem.
Keith Gaughan

8
@Keith Nie zgadzam się. Chodzi o odpowiedź na zadane pytanie.
estani

1
Zadano pytanie, jak przekonwertować ciąg znaków na wartość logiczną. Na to pytanie odpowiedziałem. Nie mam pojęcia, co uważa się za prawidłowy ciąg znaków boolowskich dla oryginalnego plakatu, a ty też. Dlatego ważniejsze jest zademonstrowanie ogólnej zasady niż udzielenie pełnej odpowiedzi na plakat. Oryginalny plakat nie wymagał od nich wypisania wszystkiego: wystarczyło wykazać ogólną zasadę. Od tego momentu każdy kompetentny uzyska odpowiedź.
Keith Gaughan

2
@dshepherd isinstance jest tam, aby upewnić się, że analizuję to, czego oczekuję. Analizuję ciągi, więc metoda car_race.lower (), która przez przypadek zwraca „1” nie powinna zwracać wartości true, powinna zgłosić błąd ValueError. Ale może to wystarczyć w innych przypadkach.
estani

2
@CivFan interesujący punkt. Chociaż próbowałem i nie było tak miło (dla mnie). elifjest zbędny ze względu na słowo zwrotne, ale daje więcej informacji bez konieczności wyszukiwania return. Ale to tylko ja, jeśli nastąpi naruszenie stylu PEP, chciałbym to zmienić. Bez żadnych innych ograniczeń zawsze powinniśmy dążyć do czytelności (i robią to standardy). Dzięki za heads-up i interesujący komentarz!
estani

7

Dict (tak naprawdę defaultdict) daje całkiem prosty sposób na wykonanie tej sztuczki:

from collections import defaultdict
bool_mapping = defaultdict(bool) # Will give you False for non-found values
for val in ['True', 'yes', ...]:
    bool_mapping[val] = True

print(bool_mapping['True']) # True
print(bool_mapping['kitten']) # False

Naprawdę łatwo jest dostosować tę metodę do konkretnego pożądanego zachowania konwersji - możesz wypełnić ją dozwolonymi wartościami Prawdy i Falsy i pozwolić na zgłoszenie wyjątku (lub zwrócenie Brak), gdy wartość nie zostanie znaleziona, lub domyślna wartość Prawda, lub domyślnie False lub cokolwiek chcesz.


5

Prawdopodobnie masz już rozwiązanie, ale dla innych, którzy szukają metody konwersji wartości na wartość logiczną przy użyciu „standardowych” wartości fałszywych, w tym None, [], {} i „” oprócz false, no i 0 .

def toBoolean( val ):
    """ 
    Get the boolean value of the provided input.

        If the value is a boolean return the value.
        Otherwise check to see if the value is in 
        ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]
        and returns True if value is not in the list
    """

    if val is True or val is False:
        return val

    falseItems = ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]

    return not str( val ).strip().lower() in falseItems

1
lepiej jest używać zestawów, not ina wybór fałszywych przedmiotów jest nieco dziwaczny.
SilentGhost

5

Możesz po prostu użyć wbudowanej funkcji eval () :

a='True'
if a is True:
    print 'a is True, a type is', type(a)
else:
    print "a isn't True, a type is", type(a)
b = eval(a)
if b is True:
    print 'b is True, b type is', type(b)
else:
    print "b isn't True, b type is", type(b)

i wynik:

a isn't True, a type is <type 'str'>
b is True, b type is <type 'bool'>

1
Działa to tylko wtedy, gdy testowane wartości są poprawnymi pythonami. „prawda” i „fałsz” spowoduje wyjątek.
Gordon Bean,

13
Co więcej, bardzo złym nawykiem jest używanie „eval” do parsowania, ponieważ eval uruchomi dowolny kod w ciągu. W niektórych sytuacjach może to stanowić ogromną całość bezpieczeństwa.
Christopher Barber

7
To jest naprawdę zła odpowiedź. Ocena dowolnego wyrażenia w celu parsowania wartości logicznej NIE jest dobrym podejściem.
sierpień

5

Jeszcze jedna opcja

from ansible.module_utils.parsing.convert_bool import boolean
boolean('no')
# False
boolean('yEs')
# True
boolean('true')
# True

Ale w produkcji, jeśli nie potrzebujesz ansibla i wszystkich jego zależności, dobrym pomysłem jest przyjrzenie się jego kodowi źródłowemu i skopiowanie potrzebnej logiki.


4

Zazwyczaj zasada oddawania do bool jest to, że kilka specjalnych literały ( False, 0, 0.0, (), [], {}) są fałszywe i wtedy wszystko jest prawdą, więc polecam, co następuje:

def boolify(val):
    if (isinstance(val, basestring) and bool(val)):
        return not val in ('False', '0', '0.0')
    else:
        return bool(val)

3

To jest wersja, którą napisałem. Łączy kilka innych rozwiązań w jedno.

def to_bool(value):
    """
    Converts 'something' to boolean. Raises exception if it gets a string it doesn't handle.
    Case is ignored for strings. These string values are handled:
      True: 'True', "1", "TRue", "yes", "y", "t"
      False: "", "0", "faLse", "no", "n", "f"
    Non-string values are passed to bool.
    """
    if type(value) == type(''):
        if value.lower() in ("yes", "y", "true",  "t", "1"):
            return True
        if value.lower() in ("no",  "n", "false", "f", "0", ""):
            return False
        raise Exception('Invalid value for boolean conversion: ' + value)
    return bool(value)

Jeśli otrzyma ciąg, oczekuje określonych wartości, w przeciwnym razie powstaje wyjątek. Jeśli nie otrzyma łańcucha, pozwól konstruktorowi bool go rozgryźć. Testowałem te przypadki:

test_cases = [
    ('true', True),
    ('t', True),
    ('yes', True),
    ('y', True),
    ('1', True),
    ('false', False),
    ('f', False),
    ('no', False),
    ('n', False),
    ('0', False),
    ('', False),
    (1, True),
    (0, False),
    (1.0, True),
    (0.0, False),
    ([], False),
    ({}, False),
    ((), False),
    ([1], True),
    ({1:2}, True),
    ((1,), True),
    (None, False),
    (object(), True),
    ]

Użyj strzamiasttype('')
pppery

3

Jeśli wiesz, że dane wejściowe będą „Prawda” lub „Fałsz”, dlaczego nie użyć:

def bool_convert(s):
    return s == "True"

Właściwie nie potrzebujesz if s else Falsetrochę. Zastanów się, jak "False" == "True"już powróci False.
Taylor Edmiston,

Jeśli nie masz pewności, czy dane wejściowe są łańcuchem, czy już wartością logiczną, możesz dodać if type(s) is bool: return s.
kontur

3

używam

# function
def toBool(x):
    return x in ("True","true",True)

# test cases
[[x, toBool(x)] for x in [True,"True","true",False,"False","false",None,1,0,-1,123]]
"""
Result:
[[True, True],
 ['True', True],
 ['true', True],
 [False, False],
 ['False', False],
 ['false', False],
 [None, False],
 [1, True],
 [0, False],
 [-1, False],
 [123, False]]
"""

2

W tym celu lubię używać trójskładnikowego operatora, ponieważ jest on bardziej zwięzły w przypadku czegoś, co wydaje się nie powinno być dłuższe niż 1 linia.

True if myString=="True" else False

1
Jak to jest bardziej zwięzłe niż my_string == „Prawda”?
S. de Melo

2

Zdaję sobie sprawę, że jest to stary post, ale niektóre rozwiązania wymagają sporo kodu, oto co wykorzystałem:

def str2bool(value):
    return {"True": True, "true": True}.get(value, False)

7
Jest to funkcjonalnie równoważne i bardziej złożone niż: zwracana wartość w („True”, „true”)
Keith Gaughan,


1

Jeśli mnie lubisz, po prostu potrzebujesz wartości logicznej ze zmiennej, która jest łańcuchem. Możesz używać destylów, jak wspomniano wcześniej przez @jzwiener. Nie mogłem jednak zaimportować i użyć modułu, jak zasugerował.

Zamiast tego używam go w ten sposób na python3.7

ciąg distutils do bool w pythonie

from distutils import util # to handle str to bool conversion
enable_deletion = 'False'
enable_deletion = bool(util.strtobool(enable_deletion))

distutils jest częścią biblioteki Python std lib, więc nie ma potrzeby instalacji. Który jest świetny! 👍


1

Chciałbym podzielić się moim prostym rozwiązaniem: użyj eval(). Przekształci ciąg Truei Falsena odpowiedni typ boolowski, JEŻELI łańcuch będzie dokładnie w formacie tytułu Truelub Falsezawsze pierwsza litera, w przeciwnym razie funkcja zgłosi błąd.

na przykład

>>> eval('False')
False

>>> eval('True')
True

Oczywiście dla zmiennej dynamicznej możesz po prostu użyć .title()do sformatowania łańcucha boolowskiego.

>>> x = 'true'
>>> eval(x.title())
True

Spowoduje to błąd.

>>> eval('true')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'true' is not defined

>>> eval('false')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'false' is not defined

0

tutaj jest włochaty, zbudowany w taki sposób, aby uzyskać wiele takich samych odpowiedzi. Zauważ, że chociaż python uważa ""się za fałszywy, a wszystkie inne ciągi za prawdziwe, TCL ma zupełnie inne zdanie na ten temat.

>>> import Tkinter
>>> tk = Tkinter.Tk()
>>> var = Tkinter.BooleanVar(tk)
>>> var.set("false")
>>> var.get()
False
>>> var.set("1")
>>> var.get()
True
>>> var.set("[exec 'rm -r /']")
>>> var.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 324, in get
    return self._tk.getboolean(self._tk.globalgetvar(self._name))
_tkinter.TclError: 0expected boolean value but got "[exec 'rm -r /']"
>>> 

Dobrą rzeczą jest to, że dość wybacza wartości, których możesz użyć. Leniwy jest przekształcanie ciągów znaków w wartościowe i higieniczny w kwestii tego, co akceptuje i odrzuca (zauważ, że jeśli powyższe oświadczenie zostanie podane w monicie tcl, spowoduje to usunięcie dysku twardego użytkownika).

złą rzeczą jest to, że wymaga, aby Tkinter był dostępny, co jest zwykle, ale nie ogólnie prawdziwe, a co ważniejsze, wymaga utworzenia instancji Tk, która jest stosunkowo ciężka.

Co jest uważane za prawdziwe lub fałszywe zależy od zachowania Tcl_GetBoolean, która uważa 0, false, noi offbyć fałszywe i 1, true, yesi onaby mogło być prawdziwe, z uwzględnieniem wielkości liter. Każdy inny ciąg, w tym pusty ciąg, powoduje wyjątek.


0
def str2bool(str):
  if isinstance(str, basestring) and str.lower() in ['0','false','no']:
    return False
  else:
    return bool(str)

pomysł: sprawdź, czy chcesz, aby ciąg był oceniany na False; w przeciwnym razie bool () zwraca True dla każdego niepustego ciągu.


0

Oto coś, co zebrałem, aby ocenić prawdziwość struny:

def as_bool(val):
 if val:
  try:
   if not int(val): val=False
  except: pass
  try:
   if val.lower()=="false": val=False
  except: pass
 return bool(val)

mniej więcej takie same wyniki jak używanie, evalale bezpieczniejsze.


0

Musiałem to zrobić ... więc może późno na imprezę - ale ktoś może uznać to za przydatne

def str_to_bool(input, default):
    """
    | Default | not_default_str | input   | result
    | T       |  "false"        | "true"  |  T
    | T       |  "false"        | "false" |  F
    | F       |  "true"         | "true"  |  T
    | F       |  "true"         | "false" |  F

    """
    if default:
        not_default_str = "false"
    else:
        not_default_str = "true"

    if input.lower() == not_default_str:
        return not default
    else:
        return default

0

Jeśli masz kontrolę nad podmiotem, który zwraca true/ false, jedną z opcji jest zwrócenie go 1/ / 0zamiast true/ false, a następnie:

boolean_response = bool(int(response))

Dodatkowa obsada intobsługuje odpowiedzi z sieci, które zawsze są ciągami.


-5

Za pomocą wbudowanej eval()funkcji Pythona i.capitalize() metody , możesz przekonwertować dowolny ciąg „prawda” / „fałsz” (niezależnie od początkowej wielkiej litery) na prawdziwą wartość logiczną języka Python.

Na przykład:

true_false = "trUE"
type(true_false)

# OUTPUT: <type 'str'>

true_false = eval(true_false.capitalize())
type(true_false)

# OUTPUT: <type 'bool'>

4
Co się stanie, jeśli ciąg zawiera #\nshutil.rmtree('/someImportantDirectory')? (Nie próbuj!)
mastov

@mastov - absurdalna opinia. Oczywiście, jeśli nie masz kontroli nad przychodzącym łańcuchem, musisz zastosować środki ostrożności, tak jak w przypadku każdego kodu. Ale jeśli kontrolujesz przepływ pracy, jest to proste rozwiązanie, które działa. Nie myl rozwiązania, które nie jest doskonałe pod każdym względem, z złą odpowiedzią.
elPastor

1
Oprócz nie wspominając o zagrożeniach (które już sprawiają, że jest to zła odpowiedź): Czy proponujesz wcześniej oczyścić dane wejściowe? Zabije to prostotę tej metody, która była jej głównym plusem.
mastov

4
Korzystanie evalczegoś ta prosta jest po prostu pytając o luki w zabezpieczeniach.
mastov

1
Nie cały kod. Ale szczególnie kod, który konwertuje ciągi znaków na inne typy, zwykle jest poza twoją kontrolą. Często nawet nie zdajesz sobie z tego sprawy. Możesz powiedzieć: „To moja baza danych (lub plik konfiguracyjny), to część mojego systemu, pod moją kontrolą”. Następnie dajesz innym modułom dostęp do bazy danych, ponieważ: „Co za szkoda? To tylko niektóre tabele z ciągami znaków”. Ale z evaltymi ciągami może pomóc komuś przejąć cały system.
mastov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.