"any()" 函数如何与 "x in y for x in z" 这样的迭代一起工作?

How does the "any()" function work with a iteration like "x in y for x in z"?

我试图了解任何函数内部发生的事情。无法理解其中的循环。谁能帮我分解一下?

with open(host_temp,'r+') as f:
    c = f.readlines()
    f.seek(0)
    for line in c:
        if not any(website in line for website in blocked_sites):
            f.write(line)
    f.truncate()

Python built-in any() 函数 returns True 如果可迭代的任何元素为真。如果可迭代对象为空,return False.

此示例 (x in y for x in z) 中 any 函数内部的语法称为 generator expression

[The syntax for generator expressions] is the same as for comprehensions, except that it is enclosed in parentheses instead of brackets or curly braces.

生成器和理解之间的主要区别在于,生成器延迟评估(根据需要),而理解立即评估所有变量。更准确地说,生成器表达式会生成一个新的生成器对象,只要调用其 next() 方法,它就会延迟计算变量。

在这种情况下,生成器表达式迭代一个名为 blocked_sites 的容器。对于 blocked_sites 中的每个 website,它正在检查该网站是否包含在文件的当前 line 中。

因此,如果在文件的一行中找到任何被阻止的网站,则会跳过该行。

代码与此类似(提供此代码的长版本):

for line in c:
    is_website_in_line = []
    for website in blocked_sites:
        is_website_in_line.append(website in line) # website in line check if a string is within another, so it returns either True or False
    if not any(is_website_in_line) # if all of the list has False values
        f.write(line)

为了补充 Christopher Peisert 的回答,我将代码拆分为如何扩展 any 语句以使其更具可读性(但并不可取 code-vice)。

with open (host_temp,'r+') as f:
  c = f.readlines()
  f.seek(0)
  for line in c:
    website_in_blocked_sites = False
    for website in blocked_sites:
      if website in line:
        website_in_blocked_sites = True
    if website_in_blocked_sites:
      f.write(line)
  f.truncate()
如果传递给它的任何元素是“真实的”(与 if x: 相同),

any() 将 return 为真。在这种情况下,它需要一个生成器作为参数。因为理解代码没有包围 [] 和 {} 以及 () 之间,这意味着它是一个生成器。

for website in blocked_sites:
    if website in line:
        return True
return False