ฟังก์ชัน python any () ทำงานอย่างไร?


114

ในหน้าเอกสาร python สำหรับanyรหัสที่เทียบเท่าสำหรับany()ฟังก์ชันจะได้รับเป็น:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

ฟังก์ชันนี้รู้ได้อย่างไรว่าฉันต้องการทดสอบองค์ประกอบใดหากเรียกมันในรูปแบบนี้

any(x > 0 for x in list)

จากนิยามฟังก์ชันทั้งหมดที่ฉันเห็นก็คือฉันกำลังส่งผ่านวัตถุที่ทำซ้ำได้ อย่างไรforห่วงรู้ว่าฉันกำลังมองหาบางสิ่งบางอย่าง> 0?

คำตอบ:


167

หากคุณใช้any(lst)คุณจะเห็นว่าlstสามารถทำซ้ำได้ซึ่งเป็นรายการของบางรายการ ถ้ามันมีอยู่[0, False, '', 0.0, [], {}, None](ซึ่งทุกคนมีค่าบูลีนของFalse) แล้วจะเป็นany(lst) Falseหากlstยังมีการใด ๆ ต่อไปนี้[-1, True, "X", 0.00001](ทั้งหมดที่ประเมินTrue) แล้วจะเป็นany(lst)True

ในโค้ดที่คุณโพสต์x > 0 for x in lstนี่เป็นประเภทที่สามารถทำซ้ำได้ซึ่งเรียกว่านิพจน์ตัวสร้าง ก่อนที่จะแสดงออกกำเนิดที่ถูกเพิ่มเข้าหลามคุณจะได้สร้างความเข้าใจในรายชื่อซึ่งมีลักษณะคล้ายกันมาก แต่มีรอบ's:[] [x > 0 for x in lst]จากlstที่มี[-1, -2, 10, -4, 20]คุณจะได้รับนี้รายการเข้าใจ[False, False, True, False, True] : จากนั้นค่าภายในนี้จะถูกส่งผ่านไปยังanyฟังก์ชันซึ่งจะส่งกลับTrueเนื่องจากมีTrueค่าอย่างน้อยหนึ่งค่า

แต่ด้วยนิพจน์ตัวสร้าง Python ไม่จำเป็นต้องสร้างรายการภายในนั้นอีกต่อไปTrue(s)และFalse(s)ค่าจะถูกสร้างขึ้นเมื่อanyฟังก์ชันวนซ้ำผ่านค่าที่สร้างขึ้นทีละรายการโดยนิพจน์ตัวสร้าง และเนื่องจากanyการลัดวงจรมันจะหยุดการทำซ้ำทันทีที่เห็นTrueค่าแรก สิ่งนี้จะเป็นประโยชน์อย่างยิ่งหากคุณสร้างlstโดยใช้สิ่งต่างๆเช่นlst = range(-1,int(1e9))(หรือxrangeถ้าคุณใช้Python2.x ) แม้ว่าการแสดงออกนี้จะสร้างกว่าพันล้านรายการanyเท่านั้นที่มีการไปเท่าที่เป็นรายการที่สามเมื่อได้รับไป1ซึ่งประเมินTrueสำหรับx>0และเพื่อให้สามารถกลับมาanyTrue

หากคุณได้สร้างความเข้าใจในรายชื่อ , Python anyจะเป็นครั้งแรกที่ได้มีการสร้างรายการพันล้านองค์ประกอบในหน่วยความจำแล้วผ่านที่ แต่ด้วยการใช้นิพจน์ตัวสร้างคุณสามารถมีฟังก์ชัน builtin ของ Python เช่นanyและallแยกออกก่อนได้ทันทีที่เห็น a TrueหรือFalseค่า


25
มันจะยังมีมูลค่าการกล่าวขวัญว่าเป็นเพียงน้ำตาลประโยคสำหรับany(x > 0 for x in list) any((x > 0 for x in list))
georg

3
คุณควรเพิ่มNoneในรายการองค์ประกอบที่มีค่าบูลีนFalse
Alok Mysore

2
เพิ่มไป @georg anyที่น้ำตาลประโยคไม่ได้เป็นพิเศษเพื่อ def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industryworker3595112

@georg ขอบคุณสำหรับคำชี้แจงนี้ นี่เป็นจุดสำคัญที่ทำให้ฉันสับสนเมื่อทดสอบโค้ดกับวงเล็บใด ๆ
MasayoMusic

39
>>> names = ['King', 'Queen', 'Joker']
>>> any(n in 'King and john' for n in names)
True

>>> all(n in 'King and Queen' for n in names)
False

เพียงแค่ลดโค้ดหลายบรรทัดให้เป็นหนึ่งเดียว คุณไม่จำเป็นต้องเขียนโค้ดยาว ๆ เช่น:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False

23

(x > 0 for x in list) ในการเรียกใช้ฟังก์ชันนั้นจะสร้างนิพจน์ของเครื่องกำเนิดไฟฟ้าเช่น

>>> nums = [1, 2, -1, 9, -5]
>>> genexp = (x > 0 for x in nums)
>>> for x in genexp:
        print x


True
True
False
True
False

ซึ่งanyใช้และลัดวงจรในการเผชิญหน้ากับวัตถุแรกที่ประเมินTrue


7

เป็นเพราะสามารถทำซ้ำได้

(x > 0 for x in list)

โปรดทราบว่าx > 0ส่งคืนอย่างใดอย่างหนึ่งTrueหรือFalseดังนั้นคุณจึงสามารถทำซ้ำได้ของบูลีน


7

พูดง่ายๆว่า any () ใช้งานได้: ตามเงื่อนไขแม้ว่าจะพบค่าการเติมเต็มหนึ่งค่าในรายการ แต่ก็ส่งคืนจริงไม่เช่นนั้นจะส่งคืนเท็จ

list = [2,-3,-4,5,6]

a = any(x>0 for x in lst)

print a:
True


list = [2,3,4,5,6,7]

a = any(x<0 for x in lst)

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