Преобразование из строки в boolean в Python?

Кто-нибудь знает, как сделать преобразование из строки в логическое значение в Python? Я нашел эту ссылку. Но это не похоже на правильный способ сделать это. То есть использование встроенных функций и т.д.

Я спрашиваю об этом потому, что я узнал о int("string") отсюда. Но при попытке bool("string") всегда возвращается True:

>>> bool("False")
True

Ответ 1

Действительно, вы просто сравниваете строку с тем, что вы ожидаете принять как отображающее true, поэтому вы можете сделать это:

s == 'True'

Или для проверки всей совокупности значений:

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

Будьте осторожны при использовании следующих функций:

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

Пустые строки оцениваются до False, но все остальное оценивает True. Поэтому это не должно использоваться для каких-либо синтаксических разборов.

Ответ 2

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

Тогда назови это так:

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

Обработка истинного и ложного явно:

Вы также можете сделать так, чтобы ваша функция явно проверяла список слов True и список слов False. Тогда, если его нет ни в одном списке, вы можете выдать исключение.

Ответ 4

Начиная с Python 2.6, теперь есть ast.literal_eval:

>>> import ast
>>> help(ast.literal_eval)
Help on function literal_eval in module ast:

literal_eval(node_or_string)
    Safely evaluate an expression node or a string containing a Python
    expression.  The string or node provided may only consist of the following
    Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
    and None.

Кажется, что вы работаете, если вы уверены, ваши строки будут либо "True", либо "False":

>>> ast.literal_eval("True")
True
>>> ast.literal_eval("False")
False
>>> ast.literal_eval("F")
Traceback (most recent call last):
  File "", line 1, in 
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
    return _convert(node_or_string)
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
    raise ValueError('malformed string')
ValueError: malformed string
>>> ast.literal_eval("'False'")
'False'

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

Ответ 5

Парсер JSON также полезен для общего преобразования строк в приемлемые типы Python.

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

Ответ 6

Если вы знаете, что строка будет "True" или "False", вы можете просто использовать eval(s).

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

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

Ответ 7

Эта версия сохраняет семантику конструкторов типа int (value) и предоставляет простой способ определения допустимых значений строк.

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

Ответ 8

Вот моя версия. Он проверяет как списки положительных, так и отрицательных значений, создавая исключение для неизвестных значений. И он не получает строку, но любой тип должен делать.

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))

Примеры прогона:

>>> 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
>>>

Ответ 9

вы всегда можете сделать что-то вроде

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

бит в parens оценил бы False. Это просто еще один способ сделать это, не выполняя фактический вызов функции.

Ответ 10

Прохладный, простой трюк (основанный на том, что @Alan Marchiori отправил), но используя yaml:

import yaml

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

Если он слишком широк, его можно уточнить, протестировав результат типа. Если yaml-возвращаемый тип является str, то он не может быть применен к какому-либо другому типу (что я могу представить в любом случае), поэтому вы можете обрабатывать его отдельно или просто позволить ему быть правдой.

Я не буду делать никаких догадок на скорости, но так как я работаю с данными yaml под Qt gui, это имеет симпатичную симметрию.

Ответ 11

Я не согласен с каким-либо решением здесь, поскольку они слишком разрешительны. Обычно это не то, что вы хотите, анализируя строку.

Итак, вот решение, которое я использую:

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)

И результаты:

>>> [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

Просто чтобы быть ясным, потому что похоже, что мой ответ каким-то образом обидел кого-то:

Дело в том, что вы не хотите проверять только одно значение и принимать другое. Я не думаю, что вы всегда хотите сопоставить Абсолютно все с не анализируемым значением. Это создает код, подверженный ошибкам.

Итак, если вы знаете, в каком коде вы его хотите.

Ответ 12

Вы можете просто использовать встроенную функцию 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)

и вывод:

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

Ответ 13

У вас, вероятно, уже есть решение, но для других, которые ищут метод для преобразования значения в логическое значение, используя "стандартные" ложные значения, включая "Нет", [], {} и "" в дополнение к false, no, и 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

Ответ 14

A dict (действительно, defaultdict) дает вам довольно простой способ сделать этот трюк:

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

Очень удобно адаптировать этот метод к точному поведению преобразования, которое вы хотите - вы можете заполнить его разрешенными значениями Truthy и Falsy и позволить ему создавать исключение (или возвращать None), когда значение не найдено, или по умолчанию на True, или по умолчанию False или что угодно.

Ответ 15

Еще один вариант

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

Но в производстве, если вам не нужен ansible и все его зависимости, хорошей идеей будет взглянуть на его исходный код и скопировать часть необходимой вам логики.

Ответ 16

Обычное правило для каста в bool состоит в том, что несколько специальных литералов (False, 0, 0.0, (), [], {}) являются ложными, а затем все остальное истинно, поэтому я рекомендую следующее:

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

Ответ 17

Это версия, которую я написал. Объединяет несколько других решений в один.

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)

Если он получает строку, он ожидает определенные значения, в противном случае возникает исключение. Если он не получает строку, просто позволяет конструктору bool понять это. Протестированы эти случаи:

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),
    ]

Ответ 18

Мне нравится использовать для этого тернарный оператор, так как он немного более кратким для того, что кажется, что оно не должно превышать 1 строки.

True if myString=="True" else False

Ответ 19

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

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

Ответ 20

Если вы знаете, что ваш ввод будет либо "True", либо "False", то почему бы не использовать:

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

Ответ 21

Используйте пакет str2bool pip install str2bool

Ответ 22

здесь волосатый, встроенный способ получить много одинаковых ответов. Обратите внимание, что хотя python считает "" ложным, а все остальные строки - истинными, TCL имеет совсем другое представление о вещах.

>>> 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 /']"
>>> 

Хорошая вещь в этом заключается в том, что она довольно прощает ценности, которые вы можете использовать. Он ленив в том, что превращает строки в ценности, и он hygenic о том, что он принимает и отклоняет (обратите внимание, что если приведенный выше оператор был указан в приглашении tcl, он удалит жесткий диск пользователей).

Плохая вещь заключается в том, что для этого требуется, чтобы Tkinter был доступен, что обычно, но не универсально верно, и, что более важно, требует создания экземпляра Tk, который является относительно тяжелым.

То, что считается истинным или ложным, зависит от поведения Tcl_GetBoolean, который считает 0, false, no и off, и 1, true, yes и on, чтобы быть истинным, нечувствительным к регистру. Любая другая строка, включая пустую строку, вызывает исключение.

Ответ 23

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

idea: проверьте, хотите ли вы, чтобы строка была оценена с помощью False; иначе bool() возвращает True для любой непустой строки.

Ответ 24

Здесь кое-что, что я собрал вместе, чтобы оценить правдивость строки:

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)

больше или меньше результатов, чем при использовании eval, но безопаснее.

Ответ 25

Я просто должен был сделать это... так, может быть, поздно на вечеринку, но кто-то может найти это полезным

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

Ответ 26

Если у вас есть контроль над предприятием, что возвращение true/false, одним из вариантов, чтобы он возвращать 1/0 вместо true/false, то:

boolean_response = bool(int(response))

Дополнительное приведение к int обрабатывает ответы из сети, которые всегда являются строковыми.

Ответ 27

Если я вам нравлюсь, просто нужно логическое значение из переменной, которая является строкой. Вы можете использовать дистилляции, как упоминалось ранее @jzwiener. Однако я не мог импортировать и использовать модуль, как он предложил.

Вместо этого я в конечном итоге использовать его таким образом на Python3.7

distutils string to bool in python

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

distutils является частью библиотеки python std, поэтому не требует установки. Что здорово! 👍

Ответ 28

Я использую

# 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]]
"""

Ответ 29

Я только что нашел это простое решение при поиске троичного оператора в Python:

(False, True)[val == "true"]

Это работает, так как в Python True = 1 и False = 0, и как только сравнение оценено, результат используется для получения элемента из кортежа по его индексу 0 или 1. Недостатком является то, что он вернет False для всего, кроме "true". ", но это хорошо работает для моего сценария анализа переменных среды.

Ответ 30

Используя встроенную eval() функцию Python и метод .capitalize(), вы можете преобразовать любую строку "true" / "false" (независимо от начальной заглавной буквы) в истинное булево значение Python.

Например:

true_false = "trUE"
type(true_false)

# OUTPUT: <type 'str'>

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

# OUTPUT: <type 'bool'>