Python 的 any 和 all 函数如何工作?

2024-11-29 08:41:00
admin
原创
190
摘要:问题描述:我试图了解any()Pythonall()内置函数的工作原理。我正在尝试比较元组,以便如果任何值不同,它将返回True,如果它们都相同,它将返回False。在这种情况下,它们如何工作以返回[False,False,False]?d是defaultdict(list)。print d['Drd2'] ...

问题描述:

我试图了解any()Pythonall()内置函数的工作原理。

我正在尝试比较元组,以便如果任何值不同,它将返回True,如果它们都相同,它将返回False。在这种情况下,它们如何工作以返回[False,False,False]?

ddefaultdict(list)

print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]

据我所知,这应该输出

# [False, True, False]

因为 (1,1) 相同,所以 (5,6) 不同,而 (0,0) 相同。

为什么所有元组的计算结果都为 False?


请参阅用 Python 的方式检查某个条件是否对列表中的任何元素成立,以了解 的实际用法any


解决方案 1:

您可以粗略地将any和分别视为all一系列逻辑orand运算符。

任何

any`True`当至少一个元素为 Truthy 时将返回。阅读有关真值测试的内容。

全部

all`True`仅当所有元素均为真时才会返回。

真值表

+-----------------------------------------+---------+---------+
|                                         |   any   |   all   |
+-----------------------------------------+---------+---------+
| All Truthy values                       |  True   |  True   |
+-----------------------------------------+---------+---------+
| All Falsy values                        |  False  |  False  |
+-----------------------------------------+---------+---------+
| One Truthy value (all others are Falsy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| One Falsy value (all others are Truthy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| Empty Iterable                          |  False  |  True   |
+-----------------------------------------+---------+---------+

注 1:官方文档中对空可迭代对象的情况进行了解释,如下所示

any

True如果可迭代对象中的任何元素为真,则返回。如果可迭代对象为空,则返回False

由于没有任何元素为真,因此False在这种情况下它会返回。

all

True如果可迭代对象的所有元素都为真(或可迭代对象为空),则返回。

由于没有任何元素为假,因此True在这种情况下它会返回。


注2:

关于anyand 的另一件重要的事情all是,一旦知道结果,它就会立即执行。优点是不需要消耗整个可迭代对象。例如,

>>> multiples_of_6 = (not (i % 6) for i in range(1, 10))
>>> any(multiples_of_6)
True
>>> list(multiples_of_6)
[False, False, False]

这里,(not (i % 6) for i in range(1, 10))是一个生成器表达式,它返回True1 到 9 之间的当前数字是否是 6 的倍数。any迭代 ,multiples_of_6当它遇到 时6,它会找到一个真值,因此它会立即返回True,其余的multiples_of_6不会被迭代。这就是我们在打印 时看到的,即 和list(multiples_of_6)的结果。7`8`9

这个优秀的东西在这个答案中运用得非常巧妙。


有了这个基本理解,如果我们看一下你的代码,你就会发现

any(x) and not all(x)

这确保了至少一个值是真值,但不是全部。这就是它返回的原因[False, False, False]。如果你真的想检查两个数字是否不同,

print [x[0] != x[1] for x in zip(*d['Drd2'])]

解决方案 2:

Pythonanyall函数如何工作?

any并获取可迭代对象,如果任何或所有元素(分别)是,all则返回。True`True`

>>> any([0, 0.0, False, (), '0']), all([1, 0.0001, True, (False,)])
(True, True)            #   ^^^-- truthy non-empty string
>>> any([0, 0.0, False, (), '']), all([1, 0.0001, True, (False,), {}])
(False, False)                                                #   ^^-- falsey

如果可迭代对象为空,则any返回False,并all返回True

>>> any([]), all([])
(False, True)

今天我在课堂上向学生们演示了allany一点。他们大多对空可迭代对象的返回值感到困惑。这样解释让他们顿时豁然开朗。

快捷行为

它们anyall都寻找允许它们停止评估的条件。我给出的第一个例子要求它们评估整个列表中每个元素的布尔值。

(请注意,列表文字本身并不是惰性求值的 - 您可以使用迭代器来获得它- 但这只是为了说明目的。)

以下是 any 和 all 的 Python 实现:

def any(iterable):
    for i in iterable:
        if i:
            return True
    return False # for an empty iterable, any returns False!

def all(iterable):
    for i in iterable:
        if not i:
            return False
    return True  # for an empty iterable, all returns True!

当然,真正的实现是用 C 编写的,并且性能更高,但您可以替换上述内容并获得与此(或任何其他)答案中的代码相同的结果。

all

all检查元素是否为False(因此它可以返回),如果所有元素都不是 ,False则返回。True`False`

>>> all([1, 2, 3, 4])                 # has to test to the end!
True
>>> all([0, 1, 2, 3, 4])              # 0 is False in a boolean context!
False  # ^--stops here!
>>> all([])
True   # gets to end, so True!

any

any工作方式是检查元素是否为真True(因此它可以返回True), then it returnsFalse if none of them wereTrue`。

>>> any([0, 0.0, '', (), [], {}])     # has to test to the end!
False
>>> any([1, 0, 0.0, '', (), [], {}])  # 1 is True in a boolean context!
True   # ^--stops here!
>>> any([])
False   # gets to end, so False!

我认为,如果您记住快捷行为,您将直观地了解它们的工作原理,而无需参考真值表。

证据allany捷径:

首先,创建一个noisy_iterator:

def noisy_iterator(iterable):
    for i in iterable:
        print('yielding ' + repr(i))
        yield i

现在让我们使用我们的例子来嘈杂地迭代列表:

>>> all(noisy_iterator([1, 2, 3, 4]))
yielding 1
yielding 2
yielding 3
yielding 4
True
>>> all(noisy_iterator([0, 1, 2, 3, 4]))
yielding 0
False

我们可以all在第一次 False 布尔检查时看到停止。

any在第一个 True 布尔检查时停止:

>>> any(noisy_iterator([0, 0.0, '', (), [], {}]))
yielding 0
yielding 0.0
yielding ''
yielding ()
yielding []
yielding {}
False
>>> any(noisy_iterator([1, 0, 0.0, '', (), [], {}]))
yielding 1
True

来源

让我们看看来源来证实上述情况。

以下是的来源any

static PyObject *
builtin_any(PyObject *module, PyObject *iterable)
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp > 0) {
            Py_DECREF(it);
            Py_RETURN_TRUE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_FALSE;
}

以下是的来源all

static PyObject *
builtin_all(PyObject *module, PyObject *iterable)
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp == 0) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_TRUE;
}

解决方案 3:

我知道这已经过时了,但我认为展示这些函数在代码中的样子可能会有所帮助。这确实说明了逻辑,在我看来比文本或表格更好。实际上,它们是用 C 而不是纯 Python 实现的,但它们是等效的。

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

def all(iterable):
    for item in iterable:
        if not item:
            return False
    return True

特别是,您可以看到空可迭代对象的结果只是自然结果,而不是特殊情况。您还可以看到短路行为;实际上,如果进行短路,工作量会更大。

当 Guido van Rossum(Python 的创建者)首次提出添加any()all()时,他通过发布上述代码片段来解释它们。

解决方案 4:

您所询问的代码来自我在此处给出的答案。它旨在解决比较多个位数组(即1和的集合)的问题0

any`all当你可以依赖值的“真实性”时,它们很有用 - 即它们在布尔上下文中的值。1 是 ,0TrueFalse,这个答案利用了这种便利。5 恰好也是True`,所以当你将它混合到你的可能输入中时……好吧。不起作用。

你可以做这样的事情:

[len(set(x)) > 1 for x in zip(*d['Drd2'])]

它缺乏前一个答案的美感(我真的很喜欢它的外观any(x) and not all(x)),但它完成了工作。

解决方案 5:

>>> any([False, False, False])
False
>>> any([False, True, False])
True
>>> all([False, True, True])
False
>>> all([True, True, True])
True

解决方案 6:

s = "eFdss"
s = list(s)
all(i.islower() for i in s )   # FALSE
any(i.islower() for i in s )   # TRUE

解决方案 7:

这个概念很简单:

M =[(1, 1), (5, 6), (0, 0)]

1) print([any(x) for x in M])
[True, True, False] #only the last tuple does not have any true element

2) print([all(x) for x in M])
[True, True, False] #all elements of the last tuple are not true

3) print([not all(x) for x in M])
[False, False, True] #NOT operator applied to 2)

4) print([any(x)  and not all(x) for x in M])
[False, False, False] #AND operator applied to 1) and 3)
# if we had M =[(1, 1), (5, 6), (1, 0)], we could get [False, False, True]  in 4)
# because the last tuple satisfies both conditions: any of its elements is TRUE 
#and not all elements are TRUE 

解决方案 8:

all() 函数用于检查集合中的每个成员是否为真。例如,all() 函数可用于更简洁地条件化以下形式的语句:

if all entre's are vegan this is a vegan restaurant

在代码中:

restaurant_is_vegan = all(x is vegan for x in menu)

如果菜单(迭代器)上的每个项目(x)对于条件(是素食主义者;x == 素食主义者)的计算结果为 True,则所有语句都将计算为 True。

更多示例在这里: https: //www.alpharithms.com/python-all-function-223809/

解决方案 9:

list = [1,1,1,0]
print(any(list)) # will return True because there is  1 or True exists
print(all(list)) # will return False because there is a 0 or False exists
return all(a % i for i in range(3, int(a ** 0.5) + 1)) # when number is divisible it will return False else return True but the whole statement is False .

解决方案 10:

我认为评估条件的逻辑有些奇怪any()。Python 文档(也在此处报告)表示至少一个条件应评估为 True,但它没有说明评估所有条件!

例如,我对下面的代码感到困惑,因为我认为它any()不能评估所有条件:

def compare(list_a, list_b):
    if any([list_a is None, list_b is None, len(list_a) == 0, len(list_b) == 0]):
        return 'no comparison'
    else:
        return 'need comparison'
    
print(compare(list_a=None, list_b=[1, 2, 3]))

上面的代码引发了异常,因为 any 仍然会评估len(list_a) == 0。在这种情况下, 使用的逻辑any()非常危险,因为我本来期望只评估第一个条件。

在这种情况下必须使用以下代码:

def compare(list_a, list_b):
    if list_a is None or list_b is None or len(list_a) == 0 or len(list_b) == 0:
        return 'no comparison'
    else:
        return 'need comparison'
    
print(compare(list_a=None, list_b=[1, 2, 3]))
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3983  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2747  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   82  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   90  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   79  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用