Bagaimana tepatnya fungsi python any () bekerja?

113

Di halaman docs python untuk any, kode yang setara untuk any()fungsi tersebut diberikan sebagai:

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

Bagaimana fungsi ini mengetahui elemen apa yang ingin saya uji jika memanggilnya dalam formulir ini?

any(x > 0 for x in list)

Dari definisi fungsi, yang bisa saya lihat adalah bahwa saya sedang melewati objek yang dapat berulang. Bagaimana forloop mengetahui bahwa saya mencari sesuatu > 0?

pythoniku
sumber

Jawaban:

166

Jika Anda menggunakan, any(lst)Anda melihat bahwa lstiterable, yang merupakan daftar beberapa item. Jika itu berisi [0, False, '', 0.0, [], {}, None](yang semuanya memiliki nilai boolean False) maka any(lst)akan False. Jika lstjuga berisi salah satu dari yang berikut [-1, True, "X", 0.00001](semuanya mengevaluasi untuk True) maka any(lst)akan True.

Dalam kode yang Anda posting,, x > 0 for x in lstini adalah jenis iterable yang berbeda, yang disebut ekspresi generator . Sebelum ekspresi Generator ditambahkan ke Python, Anda akan menciptakan pemahaman daftar , yang terlihat sangat mirip, tetapi dengan sekitarnya []'s: [x > 0 for x in lst]. Dari lstmengandung [-1, -2, 10, -4, 20], Anda akan mendapatkan ini daftar dipahami : [False, False, True, False, True]. Nilai internal ini kemudian akan diteruskan ke anyfungsi, yang akan kembali True, karena setidaknya ada satu Truenilai.

Tetapi dengan ekspresi generator , Python tidak lagi harus membuat daftar internal tersebut True(s)dan False(s), nilai akan dihasilkan saat anyfungsi melakukan iterasi melalui nilai yang dihasilkan satu per satu oleh ekspresi generator. Dan , karena anykorsleting, iterasi akan berhenti segera setelah ia melihat nilai pertama True. Ini akan sangat berguna jika Anda membuat lstmenggunakan sesuatu seperti lst = range(-1,int(1e9))(atau xrangejika Anda menggunakan Python2.x ). Meskipun ungkapan ini akan menghasilkan lebih dari satu miliar entri, anyhanya harus pergi sejauh entri ketiga ketika sampai 1, yang mengevaluasi Trueuntuk x>0, dan anydapat kembali True.

Jika Anda telah membuat pemahaman daftar , Python pertama-tama harus membuat daftar miliar elemen di memori, dan kemudian meneruskannya ke any. Tetapi dengan menggunakan ekspresi generator , Anda dapat memiliki fungsi bawaan Python seperti anydan allkeluar lebih awal, segera setelah nilai Trueatau Falseterlihat.

PaulMcG
sumber
25
Perlu juga disebutkan bahwa any(x > 0 for x in list)itu hanyalah gula sintaksis untuk any((x > 0 for x in list)).
georg
3
Anda harus menambahkan Noneke daftar elemen yang memiliki nilai booleanFalse
Alok Mysore
2
Menambahkan ke @georg, gula sintaksis tidak khusus untuk any. def b(x): return x; print b(x > 1 for x in xs) # prints <generator object ..
industri3595112
@georg Terima kasih atas klarifikasi ini. Ini adalah poin yang sangat penting yang membuat saya bingung saat menguji kode dengan tanda kurung apa pun.
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

Itu hanya mengurangi beberapa baris kode menjadi satu. Anda tidak perlu menulis kode yang panjang seperti:

for n in names:
    if n in 'King and john':
       print True
    else:
       print False
Pranjay Kaparuwan
sumber
23

(x > 0 for x in list) dalam pemanggilan fungsi itu menciptakan ekspresi generator misalnya.

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


True
True
False
True
False

Yang anymenggunakan, dan sirkuit pendek saat menghadapi objek pertama yang mengevaluasiTrue

jamylak
sumber
7

Itu karena iterable adalah

(x > 0 for x in list)

Perhatikan bahwa x > 0mengembalikan salah satu Trueatau Falsedan dengan demikian Anda memiliki boolean yang dapat diulang.

aneh
sumber
7

Cukup dengan mengatakan, any () melakukan pekerjaan ini: sesuai dengan kondisi bahkan jika ia menemukan satu nilai yang memenuhi dalam daftar, ia mengembalikan true, jika tidak ia mengembalikan salah.

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