發(fā)布于:2021-02-18 00:00:23
0
152
0
作為Python程序員,您經(jīng)常會(huì)處理布爾和條件語(yǔ)句,有時(shí)非常復(fù)雜。在這些情況下,您可能需要依賴于能夠簡(jiǎn)化邏輯和整合信息的工具。幸運(yùn)的是,Python中的any()
就是這樣一個(gè)工具。它檢查iterable中的元素并返回一個(gè)值,該值指示在布爾上下文中是否有任何元素為true,或truthy.
如何在Python中使用any()
假設(shè)您正在為雇主的招聘部門(mén)編寫(xiě)一個(gè)程序。您可能希望安排面試符合以下任何條件的候選人:
已經(jīng)了解Python
有五年或五年以上的開(kāi)發(fā)經(jīng)驗(yàn)
有學(xué)位
可以用來(lái)編寫(xiě)此條件表達(dá)式的一個(gè)工具是or
:
# recruit_developer.py
def schedule_interview(applicant):
print(f"Scheduled interview with {applicant['name']}")
applicants = [
{
"name": "Devon Smith",
"programming_languages": ["c++", "ada"],
"years_of_experience": 1,
"has_degree": False,
"email_address": "devon@email.com",
},
{
"name": "Susan Jones",
"programming_languages": ["python", "javascript"],
"years_of_experience": 2,
"has_degree": False,
"email_address": "susan@email.com",
},
{
"name": "Sam Hughes",
"programming_languages": ["java"],
"years_of_experience": 4,
"has_degree": True,
"email_address": "sam@email.com",
},
]
for applicant in applicants:
knows_python = "python" in applicant["programming_languages"]
experienced_dev = applicant["years_of_experience"] >= 5
meets_criteria = (
knows_python
or experienced_dev
or applicant["has_degree"]
)
if meets_criteria:
schedule_interview(applicant)
例如,如果申請(qǐng)人符合您的三個(gè)標(biāo)準(zhǔn)中的任何一個(gè),您可以檢查每個(gè)申請(qǐng)人的證書(shū)并安排面試。
技術(shù)細(xì)節(jié):Python的any()
和or
不限于評(píng)估布爾表達(dá)式。相反,Python對(duì)每個(gè)參數(shù)執(zhí)行真值測(cè)試,評(píng)估表達(dá)式是truthy還是falsy。例如,非零整數(shù)值被認(rèn)為是真實(shí)的,零被認(rèn)為是虛假的:
>>> 1 or 0
1
在本例中,or
將非零值1
計(jì)算為真實(shí)的,即使它不是布爾類(lèi)型。or
返回1
,不需要評(píng)估0
的真實(shí)性。在本教程的后面部分,您將了解有關(guān)or
的返回值和參數(shù)求值的更多信息。
如果您執(zhí)行此代碼,然后你會(huì)看到Susan和Sam將得到面試:
$ python recruit_developer.py
Scheduled interview with Susan Jones
Scheduled interview with Sam Hughes
公司之所以選擇安排Susan和Sam的面試,是因?yàn)镾usan已經(jīng)知道Python,Sam也有學(xué)位。請(qǐng)注意,每個(gè)候選人只需要滿足一個(gè)標(biāo)準(zhǔn)。
評(píng)估申請(qǐng)人資格的另一種方法是使用any()
。在Python中使用any()
時(shí),必須將申請(qǐng)人的憑據(jù)作為iterable參數(shù)傳遞:
for applicant in applicants:
knows_python = "python" in applicant["programming_languages"]
experienced_dev = applicant["years_of_experience"] >= 5
credentials = (
knows_python,
experienced_dev,
applicant["has_degree"],
)
if any(credentials):
schedule_interview(applicant)
在Python中使用any()
時(shí),請(qǐng)記住可以將任何iterable作為參數(shù)傳遞:
>>> any([0, 0, 1, 0])
True
>>> any(set((True, False, True)))
True
>>> any(map(str.isdigit, "hello world"))
False
any()
循環(huán)使用不同的Python iterable,測(cè)試每個(gè)元素的真值,直到找到真值或檢查每個(gè)元素。
注意:最后一個(gè)示例使用Python的內(nèi)置map()
,它返回一個(gè)迭代器,其中每個(gè)元素都是將字符串中的下一個(gè)字符傳遞給str.isdigit()
的結(jié)果。這是使用any()
進(jìn)行更復(fù)雜檢查的一種有用方法。
您可能想知道any()
是否僅僅是or
的修飾版本。在下一節(jié)中,您將了解這些工具之間的區(qū)別。
如何區(qū)分or和any()
or和之間有兩個(gè)主要區(qū)別any():
語(yǔ)法
返回值
首先,您將了解語(yǔ)法如何影響每個(gè)工具的可用性和可讀性。其次,您將學(xué)習(xí)每個(gè)工具返回的值的類(lèi)型。了解這些差異將幫助您確定哪種工具最適合給定的情況。
語(yǔ)法
or是一個(gè)運(yùn)算符,因此它需要兩個(gè)參數(shù),每個(gè)參數(shù)一個(gè)在一邊:
>>> True or False
True
any()另一方面,是一個(gè)帶有一個(gè)參數(shù)的函數(shù),它是一個(gè)循環(huán)訪問(wèn)的對(duì)象以評(píng)估真實(shí)性:
>>> any((False, True))
True
語(yǔ)法上的這種差異非常重要,因?yàn)樗鼤?huì)影響每個(gè)工具的可用性和可讀性。例如,如果您有一個(gè)Iterable,則可以將Iterable直接傳遞給any()。要從中獲得類(lèi)似的行為or,您需要使用循環(huán)或類(lèi)似的函數(shù)reduce():
>>> import functools
>>> functools.reduce(lambda x, y: x or y, (True, False, False))
True
在上面的示例中,您曾經(jīng)reduce()將iterable作為參數(shù)傳遞給or。使用可以更有效地完成此操作any,該方法直接接受可迭代對(duì)象作為參數(shù)。
為了說(shuō)明每種工具的語(yǔ)法影響其可用性的另一種方式,請(qǐng)?jiān)O(shè)想一下,如果前面的條件是True:
def knows_python(applicant):
print(f"Determining if {applicant['name']} knows Python...")
return "python" in applicant["programming_languages"]
def is_local(applicant):
print(f"Determine if {applicant['name']} lives near the office...")
should_interview = knows_python(applicant) or is_local(applicant)
如果is_local()執(zhí)行時(shí)間比較長(zhǎng),那么您knows_python()已經(jīng)返回時(shí)就不想調(diào)用它True。這稱為惰性評(píng)估或短路評(píng)估。默認(rèn)情況下,or延遲計(jì)算條件,而any不會(huì)。
在上面的示例中,該程序甚至不需要確定Susan是否是本地用戶,因?yàn)樗呀?jīng)確認(rèn)她知道Python。這樣足以安排一次面試。在這種情況下,延遲調(diào)用函數(shù)or將是最有效的方法。
為什么不使用它any()呢?您已經(jīng)在上面學(xué)到了any()將Iterable作為參數(shù),Python會(huì)根據(jù)Iterable類(lèi)型評(píng)估條件。因此,如果您使用列表,Python會(huì)在調(diào)用列表之前knows_python()和is_local()創(chuàng)建列表的同時(shí)執(zhí)行以下操作any():
should_interview = any([knows_python(applicant), is_local(applicant)])
在這里,Python會(huì)招募is_local()每個(gè)申請(qǐng)人,甚至是那些了解Python的人。因?yàn)閕s_local()執(zhí)行將花費(fèi)很長(zhǎng)時(shí)間并且有時(shí)是不必要的,所以這是邏輯的低效實(shí)現(xiàn)。
當(dāng)您使用可迭代對(duì)象時(shí),有多種方法可以使Python懶惰地調(diào)用函數(shù),例如使用map()或使用生成器表達(dá)式構(gòu)建迭代器:
any((meets_criteria(applicant) for applicant in applicants))
本示例使用生成器表達(dá)式生成布爾值,該布爾值指示申請(qǐng)人是否滿足面試條件。符合條件的申請(qǐng)人any()將在True不檢查其余申請(qǐng)人的情況下返回。但是請(qǐng)記住,這些類(lèi)型的變通辦法也存在其自身的問(wèn)題,可能并不適合每種情況。
要記住的最重要的事情是any()和之間的語(yǔ)法差異or會(huì)影響其可用性。
語(yǔ)法并不是影響這些工具可用性的唯一區(qū)別。接下來(lái),讓我們看一下不同的返回值,any()以及or它們?nèi)绾斡绊懩鷽Q定使用哪種工具。
返回值
Pythonany()和or返回不同類(lèi)型的值。any()返回一個(gè)布爾值,該布爾值指示是否在迭代器中找到真實(shí)值:
>>> any((1, 0))
True
在此示例中,any()找到一個(gè)真實(shí)值(整數(shù)1),因此它返回了布爾值True。
or另一方面,返回找到的第一個(gè)真實(shí)值,該值不一定是布爾值。如果沒(méi)有真實(shí)值,則or返回最后一個(gè)值
>>> 1 or 0
1
>>> None or 0
0
在第一示例中,or評(píng)估1,這是truthy,并且在不評(píng)估返回它0。在第二個(gè)示例中,Nonefassy是虛假的,因此接下來(lái)要or進(jìn)行評(píng)估0,這也是falsy。但是,由于沒(méi)有更多的表達(dá)式要檢查,因此or返回最后一個(gè)值0。
在確定使用哪種工具時(shí),考慮要知道對(duì)象的實(shí)際值還是僅在對(duì)象集合中某處是否存在真實(shí)值時(shí),這會(huì)很有幫助。
結(jié)論
恭喜你!你學(xué)會(huì)了插件和使用的出局any()在Python和之間的差異any()和or。通過(guò)對(duì)這兩個(gè)工具有更深入的了解,您已經(jīng)準(zhǔn)備好在自己的代碼中進(jìn)行選擇。
作者介紹
熱門(mén)博客推薦