我不完全理解这个脚本中的 any() 函数是如何工作的
I don't fully understand how the any() function in this script works
我有一个脚本可以检查列表中是否有一个或多个相同的项目。这是代码:
items = ["Blue", "Black", "Red"]
def isUnique(item):
seen = list()
return not any(i in seen or seen.append(i) for i in item)
print(isUnique(items))
如果给定列表中的所有项目都是唯一的,则打印“True”;如果列表中的一个或多个项目是唯一的,则打印“False”。有人可以为我解释脚本的 any()
部分吗,因为我不完全理解它是如何工作的?
很简单:any()
里面的表达式是一个generator。 any()
从那个生成器中提取,returns True
(和 stops)在生成器的第一个元素 True
处。如果它耗尽了发电机,那么它 returns False
.
生成器中的表达式 (i in seen or seen.append(i)
) 是一种将以下逻辑表达为一行的技巧:如果 i
在列表中,则表达式为 True
并且 any()
立即停止,否则,i
被添加到列表中并且生成器继续。
使用 set
代替 list
可以显着改善功能:
def isUnique(item):
seen = set()
return not any(i in seen or seen.add(i) for i in item)
在 set
(O[1]
) 中测试项目是否存在比在 list
(O[n]
) 中测试要快得多。
此代码的一个有趣且可能未被充分认识的方面是它适用于(可能是无限的)生成器。它将停止 在第一个重复项处从生成器中绘制。生成器将获得的后续项目根本不会被评估(具有潜在的副作用,无论是否合意)。
适用于已知和有限项目集合的不同方法如下:
def isUnique(items):
items = tuple(items) # in case items is a generator
return len(set(items)) == len(items)
这假设所有项目都适合内存。显然,如果 items
是一个非常大或无限数量的元素的生成器,这将不起作用。
这段代码有点像 hack,因为它使用了带有副作用的生成器表达式,并利用了 append
returns None
的事实,这是错误的。
命令式风格的等效代码如下:
def isUnique(items):
seen = list()
for i in items:
if i in seen or seen.append(i):
return False
return True
那里的or
还是有点奇怪——它被用于它的short-circuiting behaviour,所以append
只在i in seen
为false时被调用——所以我们可以这样重写它:
def isUnique(items):
seen = list()
for i in items:
if i in seen:
return False
else:
seen.append(i)
return True
这是等价的,因为 append
仅在 i in seen
为假时调用,而对 append
returns None
的调用意味着 return False
行不应在这种情况下执行。
编辑:有很好的答案。添加一些更简单的方法来实现想要的结果:
方法一:
items = ["Blue", "Black", "Red"]
items_set = set(items)
if len(items_set) != len(items):
# there are duplications
之所以有效,是因为集合对象“删除”了重复项。
方法二:
contains_duplicates = any(items.count(element) > 1 for element in items) # true if contains duplications and false otherwise.
见https://www.kite.com/python/answers/how-to-check-for-duplicates-in-a-list-in-python
————————————————
any
是个很棒的函数
Return True if any element of the iterable is true. If the iterable is empty, return False
但是,您的函数 isUnique
的逻辑要多一些。让我们分解一下:
首先创建一个空列表对象并将其存储在 'seen' 变量中。
for i in item
- 迭代项目列表。
i in seen
- 如果 'i' 是 'seen' 的成员,则此语句 return 为真,否则为假。
seen.append(i)
- 将 i 添加到 seen 中。这条语句 returns None if 'i' appened seen successfully.
注意 i in seen or seen.append(i)
之间的 or
语句。这意味着,如果此处的陈述之一为 True,则 or 陈述 returns 为 True。
此时,我会 运行 [i in seen or seen.append(i) for i in item]
,查看结果并进行试验。您的示例的结果是 [None, None, None]
.
基本上,对于每个项目,您都将其添加到列表中并检查它是否已经在列表中。
最后,您使用 any()
函数 - 如果可迭代对象具有 True
值,则该函数 return 为真。只有当 i in seen
将 return 为真时才会发生这种情况。
注意您正在使用 not any(...)
,如果没有重复,returns False。
有更简单、更清晰的方法来实现这一点。你应该试试!
这里需要先了解一下or
运算符的工作原理。
或者像 exp1 or exp2
它只计算先给出True或最后给出True的表达式
例如
>>> 2 or 3
2
>>> 5 or 0.0
5
>>> [] or 3
3
>>> 0 or {}
{}
现在为了您的列表理解,[i in seen or seen.append(i) for i in items]
i in seen
评估 false 和 seen.append(i)
True 以及 return None
即 list.append
return None 所以,理解包含所有 None
>>> seen = []
>>> items = ["Blue", "Black", "Red"]
>>> res = [i in seen or seen.append(i) for i in items]
>>> res
[None, None, None]
>>> any(res)
False
根据 any
文档,它是 returning false 因为它不是可迭代的或 bool。
>>> help(any)
Help on built-in function any in module builtins:
any(iterable, /)
Return True if bool(x) is True for any x in the iterable.
If the iterable is empty, return False.
python 中的 any
函数采用布尔值列表,return 是所有布尔值的 OR。
i in seen or seen.append(i) for i in item
将 i
附加到 seen
(如果它不在 seen
中)。但是如果它已经被看到那么 append() 不会 运行 因为第一部分已经是 True,并且 python 不需要知道第二部分是否为真因为 True OR'd任何事情都是真的。所以它不执行它。所以 seen
数组最终成为它所见过的唯一颜色列表。
i in seen or seen.append(i) for i in item
也是一个生成器表达式,
它生成布尔值,any
检查它生成的布尔值,即使其中一个计算结果为真,整个 any
也会 return 真。
所以第一次找到已经在 seen
数组中的项目时,any 将停止生成器并且 return True 本身。
因此,如果重复元素恰好在数组中,则不会评估更多条件,也不会向 seen
数组追加更多元素
所以如果数组有重复的元素,比如,
items = ["Blue", "Blue", "Black", "Red"]
def isUnique(item):
seen = list()
unique = not any(i in seen or seen.append(i) for i in item)
print(seen)
return unique
isUnique(items)
将导致输出,只是
['Blue']
我有一个脚本可以检查列表中是否有一个或多个相同的项目。这是代码:
items = ["Blue", "Black", "Red"]
def isUnique(item):
seen = list()
return not any(i in seen or seen.append(i) for i in item)
print(isUnique(items))
如果给定列表中的所有项目都是唯一的,则打印“True”;如果列表中的一个或多个项目是唯一的,则打印“False”。有人可以为我解释脚本的 any()
部分吗,因为我不完全理解它是如何工作的?
很简单:any()
里面的表达式是一个generator。 any()
从那个生成器中提取,returns True
(和 stops)在生成器的第一个元素 True
处。如果它耗尽了发电机,那么它 returns False
.
生成器中的表达式 (i in seen or seen.append(i)
) 是一种将以下逻辑表达为一行的技巧:如果 i
在列表中,则表达式为 True
并且 any()
立即停止,否则,i
被添加到列表中并且生成器继续。
使用 set
代替 list
可以显着改善功能:
def isUnique(item):
seen = set()
return not any(i in seen or seen.add(i) for i in item)
在 set
(O[1]
) 中测试项目是否存在比在 list
(O[n]
) 中测试要快得多。
此代码的一个有趣且可能未被充分认识的方面是它适用于(可能是无限的)生成器。它将停止 在第一个重复项处从生成器中绘制。生成器将获得的后续项目根本不会被评估(具有潜在的副作用,无论是否合意)。
适用于已知和有限项目集合的不同方法如下:
def isUnique(items):
items = tuple(items) # in case items is a generator
return len(set(items)) == len(items)
这假设所有项目都适合内存。显然,如果 items
是一个非常大或无限数量的元素的生成器,这将不起作用。
这段代码有点像 hack,因为它使用了带有副作用的生成器表达式,并利用了 append
returns None
的事实,这是错误的。
命令式风格的等效代码如下:
def isUnique(items):
seen = list()
for i in items:
if i in seen or seen.append(i):
return False
return True
那里的or
还是有点奇怪——它被用于它的short-circuiting behaviour,所以append
只在i in seen
为false时被调用——所以我们可以这样重写它:
def isUnique(items):
seen = list()
for i in items:
if i in seen:
return False
else:
seen.append(i)
return True
这是等价的,因为 append
仅在 i in seen
为假时调用,而对 append
returns None
的调用意味着 return False
行不应在这种情况下执行。
编辑:有很好的答案。添加一些更简单的方法来实现想要的结果:
方法一:
items = ["Blue", "Black", "Red"]
items_set = set(items)
if len(items_set) != len(items):
# there are duplications
之所以有效,是因为集合对象“删除”了重复项。
方法二:
contains_duplicates = any(items.count(element) > 1 for element in items) # true if contains duplications and false otherwise.
见https://www.kite.com/python/answers/how-to-check-for-duplicates-in-a-list-in-python ————————————————
any
是个很棒的函数
Return True if any element of the iterable is true. If the iterable is empty, return False
但是,您的函数 isUnique
的逻辑要多一些。让我们分解一下:
首先创建一个空列表对象并将其存储在 'seen' 变量中。
for i in item
- 迭代项目列表。
i in seen
- 如果 'i' 是 'seen' 的成员,则此语句 return 为真,否则为假。
seen.append(i)
- 将 i 添加到 seen 中。这条语句 returns None if 'i' appened seen successfully.
注意 i in seen or seen.append(i)
之间的 or
语句。这意味着,如果此处的陈述之一为 True,则 or 陈述 returns 为 True。
此时,我会 运行 [i in seen or seen.append(i) for i in item]
,查看结果并进行试验。您的示例的结果是 [None, None, None]
.
基本上,对于每个项目,您都将其添加到列表中并检查它是否已经在列表中。
最后,您使用 any()
函数 - 如果可迭代对象具有 True
值,则该函数 return 为真。只有当 i in seen
将 return 为真时才会发生这种情况。
注意您正在使用 not any(...)
,如果没有重复,returns False。
有更简单、更清晰的方法来实现这一点。你应该试试!
这里需要先了解一下or
运算符的工作原理。
或者像 exp1 or exp2
它只计算先给出True或最后给出True的表达式
例如
>>> 2 or 3
2
>>> 5 or 0.0
5
>>> [] or 3
3
>>> 0 or {}
{}
现在为了您的列表理解,[i in seen or seen.append(i) for i in items]
i in seen
评估 false 和 seen.append(i)
True 以及 return None
即 list.append
return None 所以,理解包含所有 None
>>> seen = []
>>> items = ["Blue", "Black", "Red"]
>>> res = [i in seen or seen.append(i) for i in items]
>>> res
[None, None, None]
>>> any(res)
False
根据 any
文档,它是 returning false 因为它不是可迭代的或 bool。
>>> help(any)
Help on built-in function any in module builtins:
any(iterable, /)
Return True if bool(x) is True for any x in the iterable.
If the iterable is empty, return False.
python 中的 any
函数采用布尔值列表,return 是所有布尔值的 OR。
i in seen or seen.append(i) for i in item
将 i
附加到 seen
(如果它不在 seen
中)。但是如果它已经被看到那么 append() 不会 运行 因为第一部分已经是 True,并且 python 不需要知道第二部分是否为真因为 True OR'd任何事情都是真的。所以它不执行它。所以 seen
数组最终成为它所见过的唯一颜色列表。
i in seen or seen.append(i) for i in item
也是一个生成器表达式,
它生成布尔值,any
检查它生成的布尔值,即使其中一个计算结果为真,整个 any
也会 return 真。
所以第一次找到已经在 seen
数组中的项目时,any 将停止生成器并且 return True 本身。
因此,如果重复元素恰好在数组中,则不会评估更多条件,也不会向 seen
数组追加更多元素
所以如果数组有重复的元素,比如,
items = ["Blue", "Blue", "Black", "Red"]
def isUnique(item):
seen = list()
unique = not any(i in seen or seen.append(i) for i in item)
print(seen)
return unique
isUnique(items)
将导致输出,只是
['Blue']