การกำหนดเงื่อนไข if หนึ่งบรรทัด


145

ฉันมีรหัสต่อไปนี้

num1 = 10
someBoolValue = True

ฉันต้องการตั้งค่าnum1เป็น20if someBoolValueis True; และไม่ทำอะไรเลย นี่คือรหัสของฉันสำหรับสิ่งนั้น

num1 = 20 if someBoolValue else num1

มีบางครั้งที่ฉันสามารถหลีกเลี่ยง...else num1ส่วนนั้นเพื่อให้มันดูสะอาดขึ้นได้หรือไม่? เทียบเท่ากับ

if someBoolValue:
    num1 = 20

ฉันพยายามแทนที่ด้วย...else passสิ่งนี้: num1=20 if someBoolValue else pass. สิ่งที่ฉันได้รับคือข้อผิดพลาดทางไวยากรณ์ ฉันไม่สามารถละเว้น...else num1ส่วนนั้นได้


2
เพียงแค่เปลี่ยนทั้งหมดเป็นnum1 = 20 if someBoolValue else 10. แล้วคุณเซฟnum1=10ไลน์ด้วย?
Thomas Ahle

ขอบคุณ. แต่นี่ไม่ใช่รหัสของฉัน ฉันหมายความว่าnum1มีอยู่แล้ว ...
bdhar

คำตอบ:


205

ฉันไม่คิดว่าสิ่งนี้จะเป็นไปได้ใน Python เนื่องจากสิ่งที่คุณกำลังพยายามทำอยู่อาจจะขยายไปสู่สิ่งนี้:

num1 = 20 if someBoolValue else num1

หากคุณไม่รวมelse num1ไว้คุณจะได้รับข้อผิดพลาดทางไวยากรณ์เนื่องจากฉันค่อนข้างแน่ใจว่างานนั้นต้องส่งคืนบางอย่าง

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

if someBoolValue: num1=20

ฉันไม่ใช่แฟนตัวยงnum1 = someBoolValue and 20 or num1ด้วยเหตุผลเดียวกัน ฉันต้องคิดทบทวนให้ดีว่าเส้นนั้นกำลังทำอะไรอยู่

วิธีที่ดีที่สุดในการบรรลุสิ่งที่คุณต้องการทำคือเวอร์ชันดั้งเดิม:

if someBoolValue:
    num1 = 20

เหตุผลที่เป็นคำตอบที่ดีที่สุดเป็นเพราะมันชัดเจนมากว่าคุณต้องการทำอะไรและคุณจะไม่สับสนกับตัวเองหรือใครก็ตามที่จะติดต่อกับรหัสนั้นในภายหลัง

นอกจากนี้ในฐานะที่เป็นหมายเหตุด้านข้างnum1 = 20 if someBoolValueเป็นรหัส Ruby ที่ถูกต้องเนื่องจาก Ruby ทำงานแตกต่างกันเล็กน้อย


9
ตาม PEP-308 ( docs.python.org/2.5/whatsnew/pep-308.html ) นิพจน์เงื่อนไขสามารถทำให้ชัดเจนขึ้นได้หากใส่ในพาเรนเช่นในnum1 = (20 if someBoolValue else num1).
haridsv

49

ใช้สิ่งนี้:

num1 = 20 if someBoolValue else num1

3
นี่คือสิ่งที่ฉันใช้อยู่ .. และกำลังมองหาตัวเลือกอื่นอยู่ .. ขอบคุณมาก !!
bdhar

จะเรียกบล็อกนี้ว่าอย่างไร? ฉันหมายถึงมันชื่ออะไร?
fuat

2
มันเป็นตัวดำเนินการ ternary
Chris Maes

1
เราไม่ควรใช้แนวทางนี้หากวนซ้ำชุดข้อมูลขนาดใหญ่เนื่องจากเป็นการแนะนำการมอบหมายที่ไม่จำเป็นในกรณีที่เราลงเอยด้วยคำสั่ง else
dapc

22

ในหนึ่งบรรทัด:

if someBoolValue: num1 = 20

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

if someBoolValue:
    num1 = 20

(ควรหลีกเลี่ยงหมวกอูฐเท่า ๆ กันดังนั้นควรใช้some_bool_value)

โปรดสังเกตว่าไม่มีนิพจน์ ในบรรทัดที่some_value if predicateไม่มีelseส่วนใด ๆ อยู่เนื่องจากจะไม่มีค่าส่งคืนหากเพรดิเคตเป็นเท็จ อย่างไรก็ตามนิพจน์ต้องมีค่าส่งคืนที่กำหนดไว้อย่างชัดเจนในทุกกรณี ซึ่งแตกต่างจากการใช้งานเช่น Ruby หรือ Perl


2
เนื่องจากอ่านยากและคุณอาจจะสับสนกับรหัสของคุณเองและนั่นก็ไม่ใช่ความคิดที่ดี
Frost

@bdhar ทำไมต้องใส่ไว้บรรทัดเดียว มันจะไม่เร็วขึ้น แต่คนอื่นจะอ่านได้ยากขึ้น
John La Rooy

1
@gnibbler ไม่มีเหตุผลจริงๆ ฉันกำลังมองหาแบบฟอร์มที่สั้นกว่าและอ่านง่ายกว่า ..
bdhar

17

คุณสามารถใช้สิ่งใดสิ่งหนึ่งต่อไปนี้:

(falseVal, trueVal)[TEST]

TEST and trueVal or falseVal

1
การมอบหมายแบบมีเงื่อนไข Nice one liner
minhas23

"โครงสร้าง" นั้นเรียกว่าอย่างไร? ฉันไม่เคยเห็นสิ่งนั้นมาก่อนในช่วง 6 เดือนของการเรียนรู้ Python
Guimoute

2
อย่างน้อยงานเหล่านี้ไม่ใช่งานเว้นแต่คุณจะวางไว้ตรงหน้าและอย่างที่สองงานเหล่านี้จะไม่ได้ผลตามที่อธิบายไว้ที่นี่ อันแรกสร้างทูเปิลจากนั้นเลือกองค์ประกอบหนึ่งตามดัชนี มันจะทำงานสำหรับการทดสอบที่ส่งกลับจำนวนเต็มระหว่าง -1 และ 1, หรือTrue/ Falseเนื่องจากboolเป็น subclass intของ ในทุกกรณีที่การทดสอบส่งคืนบางสิ่งที่เพิ่งจะประเมินเป็นจริงจะล้มเหลวโดยมีข้อยกเว้น อันที่สองใช้งานได้ตราบเท่าที่trueValไม่ได้ประเมินค่าเท็จซึ่งจะส่งผลfalseValให้ถูกกำหนดแม้ว่าการทดสอบจะเป็นจริงก็ตาม
Bachsau

มันสั้นมาก แต่ก็ยุ่งยากมากที่จะใช้เป็น "รูปแบบที่แนะนำ" อย่างปลอดภัยดูความคิดเห็นด้านบนจาก Bachsau ... (ดังนั้นฉันจึงลดลง)
tverrbjelke

6

ไม่ฉันเดาว่าคุณหวังว่าสิ่งที่ต้องการnum1 = 20 if someBoolValueจะได้ผล แต่ก็ไม่เป็นเช่นนั้น ฉันคิดว่าวิธีที่ดีที่สุดคือใช้ifข้อความตามที่คุณเขียนไว้:

if someBoolValue:
    num1 = 20

5
num1 = 10 + 10*(someBoolValue is True)

นั่นคือคำตอบสุดท้ายใหม่ของฉัน คำตอบก่อนหน้าเป็นดังนี้และเกินความจำเป็นสำหรับปัญหาที่ระบุไว้ Getting_too_clever not Good== นี่คือคำตอบก่อนหน้านี้ ... ยังดีถ้าคุณต้องการเพิ่มสิ่งหนึ่งสำหรับTruecond และอีกสิ่งสำหรับFalse:

num1 = 10 + (0,10)[someBoolValue is True]

ที่คุณพูดถึงnum1จะมีค่าที่ควรปล่อยให้อยู่คนเดียว ผมถือว่าnum1 = 10ตั้งแต่ที่คำสั่งแรกของโพสต์เพื่อให้การดำเนินงานที่จะได้รับคือการเพิ่ม2010

num1 = 10
someBoolValue = True

num1 = 10 + (0,10)[someBoolValue is True]

print(f'num1 = {num1}\nsomeBoolValue = {someBoolValue}')

สร้างผลลัพธ์นี้

num1 = 20
someBoolValue = True

ตอนนี้ฉันคิดว่าฉันควรจะตอบ 'num1 = 10 + 10 * (someBoolValue == True)' ปัญหาที่กำหนดให้เป็นเงื่อนไข 'False' เป็น no-op โดยทั่วไป หากจำเป็นต้องเป็นตัวเลือกในการเพิ่มค่าที่แตกต่างกันสำหรับ 'False' คำตอบก่อนหน้าจะเหมาะสมกว่า ฉันแก้ไขโพสต์ของฉันหรือทำสิ่งนี้ในความคิดเห็น
MikeyB


2

หากคุณต้องการเรียกใช้เมธอดหากบูลีนบางตัวเป็นจริงคุณสามารถใส่else Noneเพื่อยุติไตรนารี่ได้

>>> a=1
>>> print(a) if a==1 else None
1
>>> print(a) if a==2 else None
>>> a=2
>>> print(a) if a==2 else None
2
>>> print(a) if a==1 else None
>>>

1

หากโค้ดบรรทัดเดียวจะเกิดขึ้นกับคุณอย่างแน่นอน Python 3.8 จะแนะนำนิพจน์การมอบหมายที่เรียกกันติดปากว่า "ตัวดำเนินการวอลรัส"

:=

someBoolValue and (num := 20)

20จะถูกกำหนดให้หากนิพจน์บูลีนแรกคือnum Trueการกำหนดต้องอยู่ในวงเล็บที่นี่มิฉะนั้นคุณจะได้รับข้อผิดพลาดทางไวยากรณ์

num = 10
someBoolValue = True

someBoolValue and (num := 20)
print(num) # 20

num = 10
someBoolValue = False

someBoolValue and (num := 20)
print(num) # 10

0

สำหรับนักเดินทางข้ามเวลาในอนาคตจาก Google นี่คือวิธีใหม่ (มีให้ตั้งแต่ python 3.8 เป็นต้นไป):

b = 1
if a := b:
    # this section is only reached if b is not 0 or false.
    # Also, a is set to b
    print(a, b)


-1

นี่คือสิ่งที่ฉันสามารถแนะนำได้ ใช้ตัวแปรอื่นเพื่อรับส่วนคำสั่ง if และกำหนดให้เป็น num1

รหัส:

num2 =20 if someBoolValue else num1
num1=num2


-1

คุณสามารถทำได้ด้วยวิธีนี้

try:
    a = [i for i in [20] if False][0]
except IndexError:
    print("Do what ever you want here")

คุณสามารถแก้ปัญหาได้ด้วยวิธีนี้ แต่การใช้ 'try / except block' ไม่ใช่แนวทางปฏิบัติที่ดีที่สุดสำหรับ python

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