แปลงจากสตริงเป็นบูลีนใน Python หรือไม่?


745

ไม่มีใครรู้วิธีการแปลงจากสตริงเป็นบูลีนใน Python หรือไม่ ฉันพบลิงค์นี้ แต่มันก็ไม่ได้เป็นวิธีที่เหมาะสมที่จะทำ เช่นใช้ฟังก์ชั่นในตัว ฯลฯ

เหตุผลที่ฉันถามสิ่งนี้เพราะฉันได้เรียนรู้int("string")จากที่นี่ แต่เมื่อพยายามbool("string")จะส่งคืนTrue:

>>> bool("False")
True

2
ฉันได้สร้างไมโครห้องสมุดเพียงสำหรับการนี้ซึ่งรวมถึงบางคำต่างประเทศเช่น "ตาก" สำหรับโปแลนด์ "是的" ในภาษาจีนกลางจีนจะมีการประเมินเพื่อทรู ถ้าไม่ได้อย่างชัดเจนจริง ish จะประเมินการเท็จ ข้อเสนอแนะยินดีต้อนรับ ลิงค์ Github: github.com/kmonsoor/str2bool
kmonsoor

18
แทนที่จะเขียนวงล้อใหม่และเขียนรหัสที่คุณต้องใช้ในการขนส่งสินค้าคำตอบของ @ jzwienerใช้ฟังก์ชั่นจากไลบรารีมาตรฐานของไพdistutils.util.strtobool(some_string)ธ อน ในทางเทคนิคแล้วเอาต์พุตเป็นชนิดที่intมีค่า0หรือ1-> หากคุณต้องการ / ต้องการจริงๆboolคุณสามารถใช้ฟังก์ชันbool(distutils.util.strtobool(some_string))นั้นได้
Trevor Boyd Smith

1
pip install str2bool
Symon

แค่หัวขึ้น distutils.util.strtoboolไม่สามารถจัดการกับต่างประเทศใช่ / ไม่แตกต่างจากการแก้ปัญหาโดย @kmonsoor ซึ่ง แต่ไม่สามารถจัดการกับ Excel ทำไฟล์ CSV ที่มีถูก / ผิดในภาษาต่างประเทศ (เช่นVERO, FALSO) ดังนั้นการประดิษฐ์ล้อจึงจำเป็นต้องมีในบางครั้ง
Matteo Ferla

คำตอบ:


837

จริงๆคุณเพียงแค่เปรียบเทียบสตริงกับสิ่งที่คุณคาดว่าจะยอมรับว่าเป็นตัวแทนของจริงเพื่อให้คุณสามารถทำสิ่งนี้:

s == 'True'

หรือเพื่อตรวจสอบกับค่าทั้งหมด:

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

ใช้ความระมัดระวังเมื่อใช้สิ่งต่อไปนี้:

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

สตริงว่างประเมินแต่ทุกอย่างอื่นที่จะประเมินFalse Trueดังนั้นสิ่งนี้จึงไม่ควรใช้เพื่อการแยกวิเคราะห์ใด ๆ


48
+1: ไม่ง่ายกว่าs == "True"นั้นมากนัก แต่ฉันได้เห็นคนทำสิ่งนี้อย่างแท้จริง def convert (s): if s == "True": return True; กลับเท็จ
S.Lott

24
ฉันชอบที่ผลตอบแทน s == "ทรู" มากกว่าถ้า / อื่น
Dana

26
if s == "True": return True elif s == "False": return False อื่น: return Raise
ไม่รู้จัก

9
การแยกสตริงไปที่ booleans ได้ถูกใช้งานแล้วใน distutils.util.strtobool: stackoverflow.com/a/18472142/923599
jzwiener

9
ฉันรู้ว่านี่เป็นหัวข้อเก่าจริงๆ แต่ฉันต้องการยืนยันว่าฉันเพิ่งใช้เวลา 4 ชั่วโมงในการพยายามแก้ไขข้อบกพร่องของรหัส bool("False")ผิดพลาดของฉันได้พยายามที่จะโยน Trueมันจะเหวี่ยงเสมอ
Ev

304

ใช้:

bool(distutils.util.strtobool(some_string))

ค่าที่แท้จริงคือ y, ใช่, t, true, on และ 1; ค่าเท็จคือ n, no, f, false, off และ 0 เพิ่ม ValueError ถ้า val เป็นอย่างอื่น

โปรดทราบว่าdistutils.util.strtobool()ส่งคืนการแทนค่าจำนวนเต็มดังนั้นจึงจำเป็นต้องห่อด้วยbool()เพื่อรับค่าบูลีน


38
น่าเสียดายที่ผลตอบแทนนี้1/ 0ไม่ใช่True/ Falseดังนั้นคุณต้องห่อผลลัพธ์เป็นบูล () เพื่อรับบูลีนจริง:bool(distutils.util.strtobool(some_string))
Mariusz Jamro

2
ฟังก์ชั่นนั้นยั่วเย้า มันจะสมบูรณ์ถ้าจัดการจำนวนเต็มและNoneและstr(None)เป็นอินพุต
MarkHu

20
ฉันชอบสิ่งนี้กับคำตอบที่ได้รับการโหวตสูงกว่า ... มันมาจาก stdlib และทำสิ่งที่ต้องการอย่างแน่นอน โดยทั่วไปแล้วไม่มีเหตุผลที่จะต้องการของจริงboolแทนที่จะเป็น1/ 0ตราบใดที่คุณไม่ได้ทำสิ่งที่ไม่ดีเช่นif x == False... และถ้าคุณจัดการกับints และNones คุณไม่ต้องการฟังก์ชั่นพิเศษคุณสามารถตรวจสอบได้ โดยตรงif myint:หรือif not maybe_none_var:
Anentropic

4
@Secator boolเป็น sub-class ของint
Anentropic

2
ในการบันทึกข้อผิดพลาดของ Google บางคน: นำเข้า distutils และนำเข้า distutils.util เพื่อให้ใช้งานได้
Edward B.

267
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

การจัดการจริงและเท็จอย่างชัดเจน:

คุณสามารถทำให้การทำงานของคุณตรวจสอบอย่างชัดเจนกับรายการคำที่แท้จริงและรายการคำที่ผิด ถ้ามันไม่อยู่ในรายการคุณสามารถโยนข้อยกเว้นได้


29
การเพิ่มประสิทธิภาพของเล็ก ๆ น้อย ๆ สามารถทำได้โดยใช้, STR (V) .lower ()แทนv.lower () จากนั้นสามารถทำงานได้แม้จะไม่เป็นสตริงเช่น 1, 0
kmonsoor

RE: การจัดการจริง / เท็จอย่างชัดเจนคุณยังสามารถระบุค่าเริ่มต้นได้หากสตริงไม่ตรงกันเช่นเดียวกับที่พรอมต์บรรทัดคำสั่งจริง / เท็จทำงาน: ดำเนินการต่อหรือไม่ (y / N)
Johnus

113

ตัวแยกวิเคราะห์ JSON ยังมีประโยชน์สำหรับการแปลงสตริงทั่วไปเป็นชนิดหลามที่เหมาะสม

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

31
หมายเหตุวิธีนี้ใช้งานได้หากเป็นตัวพิมพ์เล็ก หากเป็นตัวพิมพ์ใหญ่คุณจะทำไม่ได้ คุณต้องโทรหา.lower()
CppLearner

107

เริ่มต้นด้วย Python 2.6 ตอนนี้มีast.literal_eval:

>>> นำเข้า ast
>>> ความช่วยเหลือ (ast.literal_eval)
ช่วยเหลือฟังก์ชั่น literal_eval ในโมดูล ast:

literal_eval (node_or_string)
    ประเมินโหนดการแสดงออกหรือสตริงที่มี Python อย่างปลอดภัย
    การแสดงออก สตริงหรือโหนดที่ระบุอาจประกอบด้วยสิ่งต่อไปนี้เท่านั้น
    โครงสร้างตัวอักษร Python: สตริง, ตัวเลข, tuples, รายการ, dicts, booleans,
    และไม่มี

สิ่งใดที่ดูเหมือนว่าจะใช้ได้ตราบใดที่คุณแน่ใจว่าสายอักขระของคุณจะเป็นอย่างใดอย่างหนึ่ง"True"หรือ"False":

>>> ast.literal_eval ("จริง")
จริง
>>> ast.literal_eval ("เท็จ")
เท็จ
>>> ast.literal_eval ("F")
Traceback (การโทรล่าสุดครั้งล่าสุด):
  ไฟล์ "", บรรทัด 1, ใน 
  ไฟล์ "/opt/Python-2.6.1/lib/python2.6/ast.py", บรรทัดที่ 68, ในตัวอักษรaleveval
    return _convert (node_or_string)
  ไฟล์ "/opt/Python-2.6.1/lib/python2.6/ast.py", บรรทัดที่ 67, ใน _convert
    เพิ่ม ValueError ('สตริงที่มีรูปแบบไม่ถูกต้อง')
ValueError: สตริงที่มีรูปแบบไม่ถูกต้อง
>>> ast.literal_eval ("'เท็จ'")
'เท็จ'

ปกติฉันจะไม่แนะนำสิ่งนี้ แต่มันมีอยู่แล้วภายในและอาจเป็นสิ่งที่ถูกต้องขึ้นอยู่กับความต้องการของคุณ


1
ไม่แน่ใจในการใช้งานทั่วไปของโซลูชันนี้ แต่ก็ดีมากในวิธีทั่วไป +1!
SingleNegationElimination

3
Gaah นั่นมันช่างน่ากลัว! จากนั้นอีกครั้งคุณไม่ว่าคุณไม่แนะนำให้มันและมันก็ไม่ตอบคำถามอย่างเรียบร้อย หาดี!
Vanessa Phipps

4
น่าเสียดายที่มันไม่ได้จัดการกับกรณีนี้ >>> ast.literal_eval ('จริง') หรือ ast.literal_eval ('TRUE') เพิ่ม >>> เพิ่ม ValueError ('สตริงที่ผิดรูป') การแก้ไขนั้นง่าย แต่ ast.literal_eval (to_test .title ())
Bhushan

ไม่ใช่คำตอบที่ดีสำหรับคำถามนี้ แต่ ... ว้าว literal_eval มีประโยชน์มาก! สตริงไปยังรายการ dict, ect
travc

มันใช้งานได้กับยูนิโค้ดหรือเปล่า? ในมุมมอง Django ของฉันฉันมีค่าขาเข้าซึ่งฉันต้องการเปลี่ยนเป็นบูลีนมันทำให้เกิดข้อยกเว้นสตริงที่ผิดรูปแบบ
Prakhar Mohan Srivastava

48

ถ้าคุณรู้ว่าสตริงจะเป็นอย่างใดอย่างหนึ่ง"True"หรือคุณก็สามารถใช้"False"eval(s)

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

ใช้สิ่งนี้เฉพาะในกรณีที่คุณแน่ใจในเนื้อหาของสตริงเนื่องจากมันจะทำให้เกิดข้อยกเว้นหากสตริงนั้นไม่มี Python ที่ถูกต้องและจะรันโค้ดที่อยู่ในสตริงด้วย


5
สายนั้นจะมาจากที่ไหนสักแห่ง if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
นูเรตทิน

4
@nurettin ดังนั้นความคิดเห็นของฉันเกี่ยวกับการใช้งานเฉพาะในกรณีที่คุณแน่ใจในเนื้อหาของสตริง
Joel Croteau

17

รุ่นนี้เก็บความหมายของตัวสร้างเช่น int (ค่า) และให้วิธีง่ายๆในการกำหนดค่าสตริงที่ยอมรับได้

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: "กรณีทดสอบ" ครั้งสุดท้ายของคุณจะเกิดข้อผิดพลาดในการโทรครั้งแรกและไม่ทดสอบคนอื่น นอกจากนี้ก็จะไม่ล้มเหลวหากมีข้อผิดพลาดจะไม่ยก
เดือนสิงหาคม

12

นี่คือเวอร์ชันของฉัน มันตรวจสอบกับทั้งรายการค่าบวกและลบเพิ่มข้อยกเว้นสำหรับค่าที่ไม่รู้จัก และมันไม่ได้รับสาย แต่ควรทำชนิดใด

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

หนึ่งสามารถรับกัดโดยนี้: to_bool(["hello"])ซึ่งควรจะเป็นการโทรที่ถูกต้องสมบูรณ์แบบถ้า[]ได้รับการสนับสนุน
Rafael T

1
ส่งคืน "ข้อยกเว้น: ค่าไม่ถูกต้องสำหรับการแปลงบูลีน: ['hello']" ซึ่งคาดว่าจะได้รับการบันทึกไว้ ในความคิดของฉันรายการว่างเปล่าเป็นเท็จอย่างชัดเจน แต่ ['เท็จ'] ไม่ชัดเจนอะไรเลยดังนั้นฉันจึงออกโดยเจตนา - นั่นเป็นคุณลักษณะที่ไม่ใช่ข้อผิดพลาด ควรเพิ่มการสนับสนุนสำหรับการคืนค่าจริงสำหรับรายการที่ไม่ว่างถ้าเป็นสิ่งที่คุณต้องการ
Petrucio

1
shure คุณเอกสารมัน to_bool([])แต่ในหนึ่งสดจริงจะไม่เรียก เขาจะทำบางสิ่งตามบรรทัดเหล่านี้: myList=someFunctionThatReturnAList`if (is_bool (myList)): ... ´มีอยู่หนึ่งรายการและต้องการทราบว่ารายการนี้ไม่มีหรือว่างเปล่า
Rafael T

ทำไมไม่ลองทำเช่นนี้: >>> def a2b (หาเรื่อง): ... default = bool (หาเรื่อง) ... ถ้า isinstance (หาเรื่อง, str): ... return arg.lower () ใน ['true', ' t ',' ใช่ ',' y ',' 1 '] ... อื่น ๆ : ... ส่งคืนค่าเริ่มต้น
ThePracticalOne

5
จุดเล็กน้อย: คุณน่าจะชอบValueErrorมากกว่าข้อยกเว้นธรรมดา
dshepherd

10

คุณสามารถทำอะไรบางอย่างเช่น

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

บิตใน parens จะประเมินเป็น False นี่เป็นอีกวิธีที่ทำได้โดยไม่ต้องทำการเรียกใช้ฟังก์ชันจริง


1
อะไรคือสิ่งที่val = "false"สายทำในตัวอย่างนี้? ทำไมถึงอยู่ที่นั่น? มันหมายความว่าอะไร?
S.Lott

9
ฉันคิดว่ามันหมายถึง 42
ภูมิศาสตร์

@Geo: ฉันเห็นด้วย; แต่คำถามที่ตอบโดยคำแถลงนั้นคืออะไร
S.Lott

นี่คือสิ่งที่ฉันกำลังมองหาประเมินฟิลด์อินพุตจากไฟล์และอ้างอิงจากผลลัพธ์ที่เก็บบูลีน ขอบคุณ.
jimh

9

เคล็ดลับง่าย ๆ (ตามสิ่งที่ @Alan Marchiori โพสต์) แต่ใช้ yaml:

import yaml

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

หากนี่กว้างเกินไปก็สามารถปรับปรุงได้โดยการทดสอบผลลัพธ์ประเภท หากประเภท yaml-return เป็น str มันจะไม่สามารถส่งไปยังประเภทอื่นได้ (ซึ่งฉันสามารถนึกถึงได้) ดังนั้นคุณสามารถจัดการมันแยกกันหรือเพียงแค่ปล่อยให้มันเป็นจริง

ฉันจะไม่คาดเดาใด ๆ ด้วยความเร็ว แต่เนื่องจากฉันทำงานกับข้อมูล yaml ภายใต้ Qt gui อยู่ดีนี่เป็นสมมาตรที่ดี


1
yamlโมดูลเป็นห้องสมุดของบุคคลที่สาม: PyYAML
ปีเตอร์ไม้

8

ฉันไม่เห็นด้วยกับวิธีแก้ปัญหาใด ๆ ที่นี่เนื่องจากพวกเขาอนุญาตเกินไป นี่ไม่ใช่สิ่งที่คุณต้องการเมื่อแยกวิเคราะห์สตริง

ดังนั้นนี่คือทางออกที่ฉันใช้:

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

เพียงเพื่อให้ชัดเจนเพราะดูเหมือนว่าคำตอบของฉันไม่พอใจใครบางคน:

ประเด็นก็คือคุณไม่ต้องการทดสอบเพียงค่าเดียวและถือว่าอีกค่าหนึ่ง ฉันไม่คิดว่าคุณต้องการแผนที่ทุกอย่างทุกอย่างกับค่าที่ไม่ได้แยกวิเคราะห์ ที่สร้างรหัสข้อผิดพลาดได้ง่าย

ดังนั้นหากคุณรู้ว่าคุณต้องการโค้ดอะไร


2
ฉันคิดว่าคุณไม่มีจุด: จุดของคำตอบคือการแสดงให้เห็นถึงหลักการทั่วไปไม่ได้บอกคนที่ถามคำถามว่าพวกเขาควรทำอย่างไร คนที่ถามคำถาม แต่เดิมคิดว่าสิ่งที่เป็นปัญหาง่ายๆ
Keith Gaughan

8
@ คี ธ ฉันไม่เห็นด้วย ประเด็นคือการตอบคำถามตามที่ถาม
estani

1
คำถามที่ถามคือวิธีแปลงสตริงเป็นบูลีน นั่นคือคำถามที่ฉันตอบ ฉันไม่รู้ว่าสิ่งใดที่ถือว่าเป็นสตริงบูลีนที่ถูกต้องสำหรับโปสเตอร์ต้นฉบับและคุณก็ไม่เข้าใจ นั่นเป็นเหตุผลที่สำคัญกว่าการแสดงให้เห็นถึงหลักการทั่วไปมากกว่าให้คำตอบเต็มโปสเตอร์ โปสเตอร์ต้นฉบับไม่ต้องการทุกสิ่งที่สะกดออกมาสำหรับพวกเขา: สิ่งที่พวกเขาต้องการคือการแสดงให้เห็นถึงหลักการทั่วไป จากนั้นทุกคนที่มีความสามารถจะได้รับคำตอบของคุณ
Keith Gaughan

2
@dew ต้อน isinstance อยู่ที่นั่นเพื่อให้แน่ใจว่าฉันแยกวิเคราะห์สิ่งที่ฉันคาดหวัง ฉันกำลังวิเคราะห์สตริงดังนั้นเมธอด car_race.lower () ที่โอกาสกลับมา '1' ไม่ควรคืนจริงมันควรโยน ValueError แต่มันอาจเพียงพอในกรณีอื่น ๆ
estani

2
@CivFan จุดที่น่าสนใจ แม้ว่าฉันจะลองมัน แต่มันก็ไม่ได้อ่านดีนัก (สำหรับฉัน) elifซ้ำซ้อนเพราะคำกลับมา returnแต่มันก็ช่วยให้คุณมีข้อมูลเพิ่มเติมได้โดยไม่ต้องสแกนหา แต่นั่นเป็นเพียงฉันถ้ามีการละเมิดสไตล์ PEP ฉันจะเปลี่ยนมัน หากไม่มีข้อ จำกัด อื่น ๆ เราควรจะอ่านได้เสมอ (และมาตรฐานทำเช่นนั้น) ขอบคุณสำหรับหัวขึ้นและแสดงความคิดเห็นที่น่าสนใจ!
estani

7

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 หรือเริ่มต้นที่เท็จหรือสิ่งที่คุณต้องการ


5

คุณอาจมีวิธีแก้ปัญหาอยู่แล้ว แต่สำหรับคนอื่น ๆ ที่กำลังมองหาวิธีการแปลงค่าเป็นค่าบูลีนโดยใช้ค่าเท็จ "มาตรฐาน" ซึ่งรวมถึงไม่มี, [], {} และ "" นอกเหนือจากเป็นเท็จไม่มีและ 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
มันจะดีกว่าที่จะใช้ชุดnot inและการเลือกรายการที่ผิดของคุณค่อนข้างแปลก
SilentGhost

5

คุณสามารถใช้ฟังก์ชัน built-in 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'>

1
ใช้งานได้เฉพาะเมื่อค่าที่ทดสอบเป็นไพ ธ อนที่ถูกต้อง "true" และ "false" จะเพิ่มข้อยกเว้น
Gordon Bean

13
นอกจากนี้มันเป็นนิสัยที่ไม่ดีจริงๆที่จะใช้ 'eval' สำหรับการแยกวิเคราะห์เพราะ eval จะเรียกใช้รหัสโดยพลการในสตริง ในบางสถานการณ์สิ่งนี้สามารถทำให้เกิดความปลอดภัยอย่างมาก
Christopher Barber

7
นี่เป็นคำตอบที่ไม่ดีจริงๆ การประเมินการแสดงออกโดยพลการเพื่อแยกบูลีนไม่ใช่วิธีที่ดี
สิงหาคม

5

อีกตัวเลือกหนึ่ง

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

แต่ในการผลิตหากคุณไม่จำเป็นต้องใช้ ansible และการอ้างอิงทั้งหมดความคิดที่ดีคือดูที่ซอร์สโค้ดและคัดลอกส่วนของตรรกะที่คุณต้องการ


4

กฎปกติสำหรับส่งไปยังบูลเป็นที่ตัวอักษรพิเศษไม่กี่ ( 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)

3

นี่คือรุ่นที่ฉันเขียน รวมโซลูชันอื่น ๆ เข้าด้วยกันเป็นหนึ่งเดียว

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)

ถ้าได้รับสายมันคาดว่าค่าเฉพาะมิฉะนั้นยกข้อยกเว้น ถ้ามันไม่ได้รับสายให้ปล่อยให้ตัวสร้างบูลหามันออกมา ทดสอบกรณีเหล่านี้:

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

ใช้strแทนtype('')
pppery

3

หากคุณรู้ว่าการป้อนข้อมูลของคุณจะเป็น "จริง" หรือ "เท็จ" ดังนั้นทำไมไม่ใช้:

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

คุณไม่ต้องการif s else Falseบิตเลย คิดว่า"False" == "True"จะกลับมาFalseอย่างไร
Taylor Edmiston

หากคุณไม่แน่ใจว่าอินพุตเป็นสตริงหรือบูลีนอยู่แล้วคุณสามารถเพิ่มif type(s) is bool: return sได้
Kontur

3

ฉันใช้

# 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

ฉันชอบใช้โอเปอร์เรเตอร์สำหรับเรื่องนี้เนื่องจากมันสั้นกระชับกว่าสำหรับบางอย่างที่รู้สึกว่ามันไม่ควรมากกว่า 1 บรรทัด

True if myString=="True" else False

1
มันกระชับกว่า my_string == 'True' อย่างไร
S. de Melo

2

ฉันรู้ว่านี่เป็นโพสต์เก่า แต่โซลูชันบางอย่างจำเป็นต้องใช้โค้ดสักหน่อยนี่คือสิ่งที่ฉันใช้

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

7
นั่นเทียบเท่ากับหน้าที่และซับซ้อนกว่า: ส่งคืนค่าใน ('จริง', 'จริง')
Keith Gaughan


1

ถ้าคุณชอบฉันก็แค่ต้องบูลีนจากตัวแปรซึ่งเป็นสตริง คุณสามารถใช้ distils ตามที่กล่าวไว้ก่อนหน้าโดย @jzwiener อย่างไรก็ตามฉันไม่สามารถนำเข้าและใช้โมดูลได้ตามที่เขาแนะนำ

ฉันจะใช้วิธีนี้ใน python3.7 แทน

แยกสตริงเพื่อบูลในหลาม

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

distutils เป็นส่วนหนึ่งของ python std lib จึงไม่จำเป็นต้องติดตั้ง ไหนดี! 👍


1

eval()ผมอยากจะแบ่งปันวิธีง่ายๆของเราใช้ มันจะแปลงสตริงTrueและFalseเป็นประเภทบูลีนที่เหมาะสมถ้าสตริงอยู่ในรูปแบบชื่อเรื่องTrueหรือFalseพิมพ์อักษรตัวแรกเสมอมิฉะนั้นฟังก์ชันจะเพิ่มข้อผิดพลาด

เช่น

>>> eval('False')
False

>>> eval('True')
True

แน่นอนว่าสำหรับตัวแปรแบบไดนามิกคุณสามารถใช้.title()เพื่อจัดรูปแบบสตริงบูลีนได้

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

นี่จะทำให้เกิดข้อผิดพลาด

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

ที่นี่มีขนดกสร้างขึ้นเพื่อให้ได้คำตอบเดียวกันมากมาย โปรดทราบว่าแม้ว่า 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 /']"
>>> 

สิ่งที่ดีเกี่ยวกับเรื่องนี้คือมันค่อนข้างให้อภัยเกี่ยวกับค่าที่คุณสามารถใช้ได้ มันขี้เกียจเกี่ยวกับการเปลี่ยนสตริงให้เป็นค่าและมันถูกสุขลักษณะเกี่ยวกับสิ่งที่ยอมรับและปฏิเสธ (โปรดสังเกตว่าหากข้อความข้างต้นถูกกำหนดที่พรอมต์ tcl มันจะลบฮาร์ดไดรฟ์ของผู้ใช้)

สิ่งที่ไม่ดีคือมันต้องการให้ Tkinter พร้อมใช้งานซึ่งโดยปกติแล้ว แต่ไม่เป็นความจริงในระดับสากลและที่สำคัญกว่านั้นต้องการให้มีการสร้างอินสแตนซ์ Tk ซึ่งค่อนข้างหนัก

สิ่งที่ถือว่าเป็นจริงหรือเท็จขึ้นอยู่กับพฤติกรรมของTcl_GetBooleanที่จะพิจารณา0, false, noและoffเป็นเท็จและ1, true, yesและonที่จะเป็นจริงกรณีตาย สตริงอื่นใดรวมถึงสตริงว่างทำให้เกิดข้อยกเว้น


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

แนวคิด: ตรวจสอบว่าคุณต้องการให้สตริงประเมินเป็น False หรือไม่ มิฉะนั้น bool () จะคืนค่า True เป็นสตริงที่ไม่ว่างเปล่า


0

นี่คือสิ่งที่ฉันรวมเข้าด้วยกันเพื่อประเมินความจริงของสตริง:

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แต่ปลอดภัยกว่า


0

ฉันต้องทำสิ่งนี้ ... อาจจะช้าไปงานเลี้ยง - แต่ใครบางคนอาจพบว่ามันมีประโยชน์

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

หากคุณมีอำนาจควบคุมเอนทิตีที่ส่งคืนtrue/ falseตัวเลือกหนึ่งคือให้ส่งคืน1/ 0แทนtrue/ falseจากนั้น:

boolean_response = bool(int(response))

การร่ายพิเศษเพื่อintจัดการการตอบสนองจากเครือข่ายซึ่งเป็นสตริงเสมอ


-5

โดยใช้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'>

4
จะเกิดอะไรขึ้นถ้าสตริงมี#\nshutil.rmtree('/someImportantDirectory')? (อย่าลอง!)
mastov

@ mastov - downvote ไร้สาระ เห็นได้ชัดว่าหากคุณไม่สามารถควบคุมสายอักขระที่เข้ามาได้คุณจะต้องวางมาตรการป้องกันไว้เช่นเดียวกับที่คุณใช้กับรหัสใด ๆ แต่ถ้าคุณควบคุมเวิร์กโฟลว์นี่เป็นทางออกที่ง่าย อย่าสับสนกับโซลูชันที่ไม่สมบูรณ์แบบในทุกด้านด้วยคำตอบที่ไม่ดี
elPastor

1
นอกเหนือจากการไม่พูดถึงอันตราย (ซึ่งได้ทำให้คำตอบที่ไม่ดี): คุณกำลังเสนอที่จะฆ่าเชื้อการป้อนข้อมูลล่วงหน้า? นั่นจะฆ่าความเรียบง่ายของวิธีนี้ซึ่งเป็นข้อดีหลักของมัน
mastov

4
การใช้evalสิ่งที่ง่าย ๆ แบบนี้ก็แค่ขอช่องโหว่
mastov

1
ไม่ใช่รหัสทั้งหมด แต่รหัสโดยเฉพาะอย่างยิ่งที่แปลงสตริงเป็นประเภทอื่นมักอยู่นอกการควบคุมของคุณ บ่อยครั้งที่คุณอาจไม่รู้ตัว คุณอาจพูดว่า: "เป็นฐานข้อมูลของฉัน (หรือไฟล์กำหนดค่า) เป็นส่วนหนึ่งของระบบของฉันภายใต้การควบคุมของฉัน" จากนั้นคุณให้สิทธิ์การเข้าถึงโมดูลอื่น ๆ กับฐานข้อมูลเพราะ: "สิ่งที่เป็นอันตรายคืออะไรมีเพียงบางตารางที่มีสตริง" แต่ด้วยevalสายเหล่านั้นอาจช่วยให้ใครบางคนที่จะใช้ระบบทั้งหมด
mastov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.