Преобразование из строки в логическое в Python?



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



EDIT:



Почему я спросил Это потому, что я узнал int("string") здесь. Я пытался bool("string") но всегда есть True.



>>> bool("False")
True
600   25  

25 ответов:

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

s == 'True'

или для проверки на целую кучу значений:

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

будьте осторожны при использовании следующие:

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

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

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 явно:

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

просто использовать:

distutils.util.strtobool(some_string)

http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

истинные значения y, да, t, true, on и 1; ложные значения n, нет, f, false, off и 0. Поднимает ValueError, если val-это что-то еще.

начиная с 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'

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

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

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

эта версия сохраняет семантику конструкторов, таких как 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

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

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

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

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

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

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

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

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

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

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

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

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

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

import yaml

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

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

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

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

дикт (действительно, 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

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

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

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

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

True if myString=="True" else False

обычное правило для приведения к 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)

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

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

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

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

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

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

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

вот волосатый, встроенный способ получить многие из тех же ответов. Обратите внимание, что хотя 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 правда, без учета регистра. Любая другая строка, включая пустую строку, вызывает исключение.

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

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

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

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 но безопаснее.

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

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

если у вас есть контроль над объектом, который возвращается true/false, один из вариантов-это возвращение 1/0 вместо true/false, тогда:

boolean_response = bool(int(response))

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

С помощью встроенного Python

Comments

    Ничего не найдено.