如何在Python中使用any()

发布于:2021-02-18 00:00:23

0

128

0

基础知识 python 程序员 any()

作为Python程序员,您经常会处理布尔和条件语句,有时非常复杂。在这些情况下,您可能需要依赖于能够简化逻辑和整合信息的工具。幸运的是,Python中的any()就是这样一个工具。它检查iterable中的元素并返回一个值,该值指示在布尔上下文中是否有任何元素为true,或truthy.

如何在Python中使用any()

假设您正在为雇主的招聘部门编写一个程序。您可能希望安排面试符合以下任何条件的候选人:

  1. 已经了解Python

  2. 有五年或五年以上的开发经验

  3. 有学位

可以用来编写此条件表达式的一个工具是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)

例如,如果申请人符合您的三个标准中的任何一个,您可以检查每个申请人的证书并安排面试。

技术细节:Python的any()or不限于评估布尔表达式。相反,Python对每个参数执行真值测试,评估表达式是truthy还是falsy。例如,非零整数值被认为是真实的,零被认为是虚假的:

>>> 1 or 0
1

在本例中,or将非零值1计算为真实的,即使它不是布尔类型。or返回1,不需要评估0的真实性。在本教程的后面部分,您将了解有关or

的返回值和参数求值的更多信息。

如果您执行此代码,然后你会看到Susan和Sam将得到面试:

$ python recruit_developer.py
Scheduled interview with Susan Jones
Scheduled interview with Sam Hughes

公司之所以选择安排Susan和Sam的面试,是因为Susan已经知道Python,Sam也有学位。请注意,每个候选人只需要满足一个标准。

评估申请人资格的另一种方法是使用any()。在Python中使用any()时,必须将申请人的凭据作为iterable参数传递:

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()时,请记住可以将任何iterable作为参数传递:

>>> any([0, 0, 1, 0])
True

>>> any(set((True, False, True)))
True

>>> any(map(str.isdigit, "hello world"))
False

any()循环使用不同的Python iterable,测试每个元素的真值,直到找到真值或检查每个元素。

注意:最后一个示例使用Python的内置map(),它返回一个迭代器,其中每个元素都是将字符串中的下一个字符传递给str.isdigit()的结果。这是使用any()进行更复杂检查的一种有用方法。

您可能想知道any()是否仅仅是or的修饰版本。在下一节中,您将了解这些工具之间的区别。

如何区分or和any()

or和之间有两个主要区别any():

  • 语法

  • 返回值

首先,您将了解语法如何影响每个工具的可用性和可读性。其次,您将学习每个工具返回的值的类型。了解这些差异将帮助您确定哪种工具最适合给定的情况。

语法

or是一个运算符,因此它需要两个参数,每个参数一个在一边:

>>> True or False
True

any()另一方面,是一个带有一个参数的函数,它是一个循环访问的对象以评估真实性:

>>> any((False, True))
True

语法上的这种差异非常重要,因为它会影响每个工具的可用性和可读性。例如,如果您有一个Iterable,则可以将Iterable直接传递给any()。要从中获得类似的行为or,您需要使用循环或类似的函数reduce():

>>> import functools
>>> functools.reduce(lambda x, y: x or y, (True, False, False))
True

在上面的示例中,您曾经reduce()将iterable作为参数传递给or。使用可以更有效地完成此操作any,该方法直接接受可迭代对象作为参数。

为了说明每种工具的语法影响其可用性的另一种方式,请设想一下,如果前面的条件是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()执行时间比较长,那么您knows_python()已经返回时就不想调用它True。这称为惰性评估或短路评估。默认情况下,or延迟计算条件,而any不会。

在上面的示例中,该程序甚至不需要确定Susan是否是本地用户,因为它已经确认她知道Python。这样足以安排一次面试。在这种情况下,延迟调用函数or将是最有效的方法。

为什么不使用它any()呢?您已经在上面学到了any()将Iterable作为参数,Python会根据Iterable类型评估条件。因此,如果您使用列表,Python会在调用列表之前knows_python()和is_local()创建列表的同时执行以下操作any():

should_interview = any([knows_python(applicant), is_local(applicant)])

在这里,Python会招募is_local()每个申请人,甚至是那些了解Python的人。因为is_local()执行将花费很长时间并且有时是不必要的,所以这是逻辑的低效实现。

当您使用可迭代对象时,有多种方法可以使Python懒惰地调用函数,例如使用map()或使用生成器表达式构建迭代器:

any((meets_criteria(applicant) for applicant in applicants))

本示例使用生成器表达式生成布尔值,该布尔值指示申请人是否满足面试条件。符合条件的申请人any()将在True不检查其余申请人的情况下返回。但是请记住,这些类型的变通办法也存在其自身的问题,可能并不适合每种情况。

要记住的最重要的事情是any()和之间的语法差异or会影响其可用性。

语法并不是影响这些工具可用性的唯一区别。接下来,让我们看一下不同的返回值,any()以及or它们如何影响您决定使用哪种工具。

返回值

Pythonany()和or返回不同类型的值。any()返回一个布尔值,该布尔值指示是否在迭代器中找到真实值:

>>> any((1, 0))
True

在此示例中,any()找到一个真实值(整数1),因此它返回了布尔值True。

or另一方面,返回找到的第一个真实值,该值不一定是布尔值。如果没有真实值,则or返回最后一个值

>>> 1 or 0
1

>>> None or 0
0

在第一示例中,or评估1,这是truthy,并且在不评估返回它0。在第二个示例中,Nonefassy是虚假的,因此接下来要or进行评估0,这也是falsy。但是,由于没有更多的表达式要检查,因此or返回最后一个值0。

在确定使用哪种工具时,考虑要知道对象的实际值还是仅在对象集合中某处是否存在真实值时,这会很有帮助。

结论

恭喜你!你学会了插件和使用的出局any()在Python和之间的差异any()和or。通过对这两个工具有更深入的了解,您已经准备好在自己的代码中进行选择。