วิธีการแปลง 'false' เป็น 0 และ 'true' เป็น 1 ใน Python


120

มีวิธีแปลงtruetype unicodeเป็น 1 และfalsetype unicodeเป็น 0 (ใน Python) หรือไม่?

ตัวอย่างเช่น: x == 'true' and type(x) == unicode

ฉันต้องการ x = 1

PS: ฉันไม่ต้องการใช้if- else.

คำตอบ:


165

ใช้int()ในการทดสอบบูลีน:

x = int(x == 'true')

int()เปลี่ยนบูลลงหรือ1 0โปรดทราบว่าค่าใด ๆ ที่ไม่เท่ากับ'true'จะส่ง0คืน


นี่เป็นคำตอบที่ยอดเยี่ยมยกเว้นว่าทุกสิ่งที่ 'จริง' จะถูกตีความว่าเป็น '0' ไม่แน่ใจว่าจะเหมาะกับความต้องการของ OPs หรือไม่
Abhijit

แม้ว่าอาจเป็นสิ่งที่ OP ต้องการ แต่ก็ไม่ตรงกับคำถามที่ถาม python 2.7 พวกเขาอย่างชัดเจนถามว่าการทำงานกับชนิด Unicode strและไม่ได้ระบุพฤติกรรมสำหรับประเภท
Wim

1
@wim จริงๆแล้วคำถามไม่เคยพูดถึงเวอร์ชัน python เลยนับประสาความจริงที่ว่าควรเป็น python2 7 . โปรดทราบว่าใน python2 u'true' == 'true'ดังนั้นฟังก์ชันจะทำงานอย่างถูกต้องจากประเภทอินพุต [ระหว่างstrและunicode]
Bakuriu

แต่บาคุริวนั่นคือประเด็นของฉัน "ปัญหา" ก็คือu'true' == 'true'และเราไม่รู้ว่ากรณีการใช้งานคืออะไร type(x) != unicodeบางทีพวกเขาต้องการพฤติกรรมที่แตกต่างกันสำหรับสถานการณ์ที่
Wim

1
@AlbertChen: ไม่เพราะอาร์เรย์ numpy ออกอากาศการเปรียบเทียบและไม่ได้สร้างค่าบูลีน การเปรียบเทียบจะสร้างอาร์เรย์ของค่าบูลีนแทน ฉันไม่แน่ใจว่าคุณคาดหวังอะไรจากการarrayvalue == 'true'เปรียบเทียบคำถามที่ฉันตอบที่นี่เป็นค่าสตริง (unicode) เท่านั้น
Martijn Pieters

137

ถ้าBเป็นอาร์เรย์บูลีนให้เขียน

B = B*1

(รหัสบิตเป็นกอล์ฟ)


1
สิ่งเดียวกันนี้ใช้ได้กับค่าเดียว นี่มันเยี่ยมมาก!
user31415

2
ไม่ทำงานสำหรับฉันใน Python 3 (อาร์เรย์ยังคงเป็นบูลีน) แต่ใช้numpy.multiply(B,1)ผลงาน.
Alaa M.

สิ่งนี้ใช้ได้กับฉันใน python 3! และโซลูชั่นที่ยอดเยี่ยมเช่นนี้ โอ้ฉัน
alwaysaskingquestions

@Ourobours: การพยายามทำตามคำแนะนำของคุณไม่ได้ผลสำหรับฉันในขณะที่การดูดซับแบบดั้งเดิมให้ผลลัพธ์ที่ดี แต่ผลลัพธ์ที่สามารถใช้งานได้B=map(int,B)กลับส่งผลตามแผนที่ใน python 3 สำหรับฉัน
Eulenfuchswiesel

1
@Eulenfuchswiesel เนื่องจากแผนที่ส่งคืนตัววนซ้ำใน Python3 หากต้องการใช้เป็นรายการให้โยนเป็นรายการดังนี้: B = list (map (int, B))
Gigi Bayte 2


9

นี่เป็นอีกวิธีแก้ปัญหาของคุณ:

def to_bool(s):
    return 1 - sum(map(ord, s)) % 2
    # return 1 - sum(s.encode('ascii')) % 2  # Alternative for Python 3

มันทำงานได้เพราะผลรวมของรหัส ASCII ของ'true'มีที่448ซึ่งเป็นแม้กระทั่งในขณะที่ผลรวมของรหัส ASCII ของ'false'มีที่523ซึ่งเป็นเลขคี่


สิ่งที่ตลกเกี่ยวกับการแก้ปัญหานี้คือการที่ผลของมันเป็นแบบสุ่มสวยถ้าใส่เป็นไม่ได้อย่างใดอย่างหนึ่งหรือ'true' 'false'ครึ่งหนึ่งของเวลาที่มันจะกลับมาและอีกครึ่งหนึ่ง0 1ตัวแปรที่ใช้encodeจะเพิ่มข้อผิดพลาดในการเข้ารหัสหากอินพุตไม่ใช่ ASCII (จึงเป็นการเพิ่มพฤติกรรมที่ไม่ได้กำหนด)


อย่างจริงจังฉันเชื่อว่าวิธีแก้ปัญหาที่อ่านง่ายและเร็วที่สุดคือการใช้if:

def to_bool(s):
    return 1 if s == 'true' else 0

ดู microbenchmarks:

In [14]: def most_readable(s):
    ...:     return 1 if s == 'true' else 0

In [15]: def int_cast(s):
    ...:     return int(s == 'true')

In [16]: def str2bool(s):
    ...:     try:
    ...:         return ['false', 'true'].index(s)
    ...:     except (ValueError, AttributeError):
    ...:         raise ValueError()

In [17]: def str2bool2(s):
    ...:     try:
    ...:         return ('false', 'true').index(s)
    ...:     except (ValueError, AttributeError):
    ...:         raise ValueError()

In [18]: def to_bool(s):
    ...:     return 1 - sum(s.encode('ascii')) % 2

In [19]: %timeit most_readable('true')
10000000 loops, best of 3: 112 ns per loop

In [20]: %timeit most_readable('false')
10000000 loops, best of 3: 109 ns per loop

In [21]: %timeit int_cast('true')
1000000 loops, best of 3: 259 ns per loop

In [22]: %timeit int_cast('false')
1000000 loops, best of 3: 262 ns per loop

In [23]: %timeit str2bool('true')
1000000 loops, best of 3: 343 ns per loop

In [24]: %timeit str2bool('false')
1000000 loops, best of 3: 325 ns per loop

In [25]: %timeit str2bool2('true')
1000000 loops, best of 3: 295 ns per loop

In [26]: %timeit str2bool2('false')
1000000 loops, best of 3: 277 ns per loop

In [27]: %timeit to_bool('true')
1000000 loops, best of 3: 607 ns per loop

In [28]: %timeit to_bool('false')
1000000 loops, best of 3: 612 ns per loop

แจ้งให้ทราบว่าifการแก้ปัญหาคืออย่างน้อย 2.5 เท่าครั้งได้เร็วขึ้นกว่าทุกโซลูชั่นอื่น ๆ มันไม่สมเหตุสมผลที่จะวางเป็นข้อกำหนดในการหลีกเลี่ยงการใช้ifs ยกเว้นว่านี่เป็นการบ้านบางอย่าง (ซึ่งในกรณีนี้คุณไม่ควรถามสิ่งนี้ตั้งแต่แรก)


7

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

>>> def str2bool(st):
try:
    return ['false', 'true'].index(st.lower())
except (ValueError, AttributeError):
    raise ValueError('no Valid Conversion Possible')


>>> str2bool('garbaze')

Traceback (most recent call last):
  File "<pyshell#106>", line 1, in <module>
    str2bool('garbaze')
  File "<pyshell#105>", line 5, in str2bool
    raise TypeError('no Valid COnversion Possible')
TypeError: no Valid Conversion Possible
>>> str2bool('false')
0
>>> str2bool('True')
1

2
ทำไมTypeError? หากสตริงไม่มี'true'หรือ'false'มีข้อผิดพลาดค่า ถ้าใส่ไม่เป็นสตริงคุณจะได้รับ (99.99% ของครั้ง) ความAttributeErrorแทนเพราะฉะนั้นมันไม่มีประโยชน์ที่จะจับและอีกยกเป็นValueError TypeError
Bakuriu

@ บาคุริว: ฉันเห็นด้วย TypeError ไม่สามารถใช้ได้ที่นี่
Abhijit

@ บาคุริว: ด้วยความอยากรู้คุณช่วยยกตัวอย่างindexAttributeError ได้ไหม?
จอร์เจีย

@Bakuriu: return ['false', 'true'].index(s) except (ValueError, AttributeError)ผมคิดว่าผมค่อนข้างหมายถึงการโพสต์ของคุณด้านล่าง:
จอร์เจีย

@ thg435 ในโพสต์นั้นฉันเพิ่งคัดลอกและตัดสินใจที่จะลบการlower()โทรออกเนื่องจากนี่เป็นทางออกเดียวที่ทำการคำนวณพิเศษนี้และการรวมไว้ในมาตรฐานไมโครจะไม่ถูกต้อง แน่นอนว่าแม้try...exceptจะใช้เวลาสักหน่อย แต่ความแตกต่างนั้นเล็กน้อยหากไม่มีการเพิ่มข้อยกเว้น (เช่น20nsน้อยกว่าหรือมากกว่านั้น)
Bakuriu

0

บูลเป็น int: x = (x == 'true') + 0

ตอนนี้ x มี 1 ถ้าx == 'true'อื่น 0

หมายเหตุ: x == 'true'จะส่งคืนบูลซึ่งจะถูกพิมพ์เป็น int ที่มีค่า (1 ถ้าค่าบูลเป็น True else 0) เมื่อบวกด้วย 0


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.