Chuyển đổi giá trị True / False được đọc từ tệp thành boolean


86

Tôi đang đọc một True - Falsegiá trị từ một tệp và tôi cần chuyển nó thành boolean. Hiện tại, nó luôn chuyển đổi nó thành Truengay cả khi giá trị được đặt thành False.

Đây là một MWEtrong những điều tôi đang cố gắng làm:

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'

Các file.dattập tin cơ bản bao gồm một chuỗi duy nhất với giá trị Truehoặc Falsebên bằng văn bản. Sự sắp xếp trông rất phức tạp vì đây là một ví dụ tối thiểu từ một mã lớn hơn nhiều và đây là cách tôi đọc các tham số vào nó.

Tại sao flagluôn chuyển đổi thành True?


1
pip cài đặt str2bool
Symon

Câu trả lời:


100

bool('True')bool('False')luôn trả về Truevì chuỗi 'True' và 'False' không trống.

Để trích dẫn một người đàn ông vĩ đại (và tài liệu Python ):

5.1. Kiểm tra giá trị sự thật

Bất kỳ đối tượng nào cũng có thể được kiểm tra giá trị chân lý, để sử dụng trong điều kiện if hoặc while hoặc như toán hạng của các phép toán Boolean bên dưới. Các giá trị sau được coi là sai:

  • zero của bất kỳ loại số, ví dụ, 0, 0L, 0.0, 0j.
  • bất kỳ chuỗi rỗng, ví dụ, '', (), [].

Tất cả các giá trị khác được coi là đúng - vì vậy các đối tượng thuộc nhiều loại luôn đúng.

Việc xây dựng trong boolsử dụng chức năng thủ tục kiểm tra thật chuẩn. Đó là lý do tại sao bạn luôn nhận được True.

Để chuyển đổi một chuỗi thành boolean, bạn cần làm như sau:

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

23
Bạn có thể biến nó thành một "anh hùng" ValueErrorbằng cách làm raise ValueError("Cannot covert {} to a bool".format(s)).
SethMMorton

Chọn cái này vì nó không sử dụng gói bổ sung. Cảm ơn các bạn!
Gabriel

1
Có gì sai với "gói bổ sung"? Bạn đang đề cập đến ast? Nó là một phần của thư viện tiêu chuẩn, vì vậy nó không thực sự bổ sung.
SethMMorton

4
nó có thể là một câu hỏi ngớ ngẩn nhưng tại sao boolkhông chuyển đổi các chuỗi TrueFalsethành các giá trị boolean TrueFalse? Có vẻ là hành vi không nhất quán từ những gì inthiện. Tôi chỉ thực sự tò mò tại sao lý do của tôi là sai và tại sao lựa chọn khác lại là quyết định.
Charlie Parker,

1
Bất cứ khi nào so sánh các chuỗi, tôi muốn làm phẳng trường hợp, (nếu có). ví dụ tôi sẽ sử dụng: nếu s.upper () == 'TRUE': return Đúng elif s.upper () == 'FALSE' trở lại False
Bill Kidd

75

bạn có thể dùng distutils.util.strtobool

>>> from distutils.util import strtobool

>>> strtobool('True')
1
>>> strtobool('False')
0

Truegiá trị y, yes, t, true, on1; Falsegiá trị n, no, f, false, off0. Tăng ValueErrornếu val là bất cứ điều gì khác.


22
Thậm chí tốt hơn, làm bool(strtobool(my_string))để cast đầu ra như là một biến True / False boolean
AlexG

10
@AlexG điên rồ rằng một hàm được gọi strtobool()thực tế không trả về abool
dericke

61

Sử dụng ast.literal_eval:

>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False

Tại sao cờ luôn chuyển đổi thành True?

Các chuỗi không trống luôn là True trong Python.

Liên quan: Kiểm tra giá trị sự thật


Nếu NumPy là một tùy chọn, thì:

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

nó có thể là một câu hỏi ngớ ngẩn nhưng tại sao boolkhông chuyển đổi các chuỗi TrueFalsethành các giá trị boolean TrueFalse? Có vẻ là hành vi không nhất quán từ những gì inthiện. Tôi chỉ thực sự tò mò tại sao lý do của tôi là sai và tại sao lựa chọn khác lại là quyết định.
Charlie Parker,

2
ast.literal_eval ('false') đưa ra một ngoại lệ mà tôi nghĩ khiến nó ít được mong đợi hơn
Chris

@Chris Bạn luôn có thể bao bọc nó xung quanh thử ngoại trừ trong một chức năng tùy chỉnh thay vì sử dụng nó trực tiếp sau đó.
Ashwini Chaudhary

@HewwoCraziness Nó chỉ phân tích cú pháp các biểu thức chứ không phải bất kỳ mã ngẫu nhiên nào.
Ashwini Chaudhary

15

Giải pháp sạch nhất mà tôi đã thấy là:

from distutils.util import strtobool
def string_to_bool(string):
    return bool(strtobool(str(string)))

Chắc chắn, nó yêu cầu nhập, nhưng nó có xử lý lỗi thích hợp và yêu cầu rất ít mã được viết (và thử nghiệm).


Điều này không hoạt động trừ khi giá trị đầu vào thực sự có thể là boolean, nếu không, nó dường như gây ra lỗi giá trị. Điều duy nhất tôi có thể nghĩ đến là thêm một thử / ngoại trừ vào hàm của bạn và ValueErrortrả về sai.
Ari

13

Tôi không đề xuất đây là câu trả lời tốt nhất, chỉ là một giải pháp thay thế nhưng bạn cũng có thể làm điều gì đó như:

flag = reader[0] == "True"

cờ sẽ là Truetrình đọc id [0] là "Đúng", nếu không sẽ là False.


10

Hiện tại, nó đang đánh giá Truevì biến có một giá trị. Có một ví dụ điển hình được tìm thấy ở đây về những gì sẽ xảy ra khi bạn đánh giá các kiểu tùy ý dưới dạng boolean.

Tóm lại, những gì bạn muốn làm là cô lập chuỗi 'True'hoặc 'False'và chạy evaltrên nó.

>>> eval('True')
True
>>> eval('False')
False

4
@samyi Thật nguy hiểm khi sử dụng phương thức eval. stackoverflow.com/questions/1832940/…
M07

1
FYI. Đây là một ý tưởng khủng khiếp và bạn không bao giờ nên sử dụng eval(). Theo tôi, nên loại bỏ nó khỏi ngôn ngữ.
Nostalg.io

Điều này RẤT RẤT RẤT XẤU vì nó là một lỗ hổng bảo mật. Nếu bạn sử dụng eval()trên dữ liệu thô từ một tệp thì điều đó có nghĩa là bất kỳ ai có quyền ghi vào tệp đó đều có thể thực thi mã ở cùng cấp quyền với tập lệnh của bạn.
Keith Ripley

Ngoài ra, nếu giá trị không có lỗi chính tả python chính xác, ví dụ eval('false'), eval('FALSE')nó sẽ báo lỗi.
kev

5

Bạn có thể sử dụng dict để chuyển đổi chuỗi thành boolean. Thay đổi dòng này flag = bool(reader[0])thành:

flag = {'True': True, 'False': False}.get(reader[0], False) # default is False

5

Nếu bạn muốn phân biệt chữ hoa chữ thường, bạn có thể làm:

b = True if bool_str.lower() == 'true' else False

Ví dụ sử dụng:

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

3

pip cài đặt str2bool

>>> from str2bool import str2bool
>>> str2bool('Yes')
True
>>> str2bool('FaLsE')
False

2

Bạn có thể làm với json.

In [124]: import json

In [125]: json.loads('false')
Out[125]: False

In [126]: json.loads('true')
Out[126]: True

2

Chỉ cần nói thêm rằng nếu giá trị chân lý của bạn có thể thay đổi, ví dụ: nếu nó là đầu vào từ các ngôn ngữ lập trình khác nhau hoặc từ các loại khác nhau, thì một phương pháp mạnh mẽ hơn sẽ là:

flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support

Và một biến thể hiệu quả hơn sẽ là (tra cứu thiết lập là O (1)):

TRUTHS = set(['True','true',1,'T','t','1'])
flag = value in truths


0

Nếu bạn cần cách nhanh chóng để chuyển đổi chuỗi thành bools (hoạt động với hầu hết các chuỗi), hãy thử.

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


0

Sử dụng số để chuyển đổi "True" thành True:

def str_to_bool(s: str):
    status = {"True": True,
                "False": False}
    try:
        return status[s]
    except KeyError as e:
        #logging
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.