用于字典值(非键)的内置“all()”函数

2024-04-24 00:56:59 发布

您现在位置:Python中文网/ 问答频道 /正文

是否有一个内置函数可以比较字典的值,比如内置的all()函数可以比较一个列表或元组,并返回TrueFalse+字典键?你知道吗

我想要实现的是给all()函数一个字典而不是一个列表。all()的默认行为是返回True,如果缺少元素或元素错误:

>>> all([1,2,3,4,0])
False
>>> all(['hello', 'world', ''])
False
>>> all(['hello', 'world', None])
False
>>> all([1,2,3,4])
True
>>> all(['hello', 'world'])
True

使用vanilla all()函数,它只返回TrueFalse值,如果我想检查这些布尔值,就可以进行比较。但是,我无法知道哪些值是错误的,以便告诉用户出现问题的原因。你知道吗

我已经创建了一个函数,这个函数就是这个函数。除布尔值外,它还返回值为false的元素键:

# dictionary all function (working with 3.x)
def dict_all(iterable):
    for key in iterable:
        if not iterable[key]:
            return False, key
    return True

我希望它早点退出,我们不需要测试所有的值。你知道吗

有没有一个内置的函数可以做到这一点?如果没有,为什么不呢?它似乎在各种情况下都很有用。你知道吗

我将它用于一个函数,其中每个关键字参数都有一个默认值None,以便在用户未设置值时提供默认值。我使用dict_all()函数在返回False, key时提供错误消息。你知道吗

例如:

dictionary = {'jira_key' : 'REDACTED',
    'summary' : 'this is a test',
    'desc' : 'this is a description',
    'req_type' : 'PMV',
    'comp_type' : None}

预期结果是回报False, 'comp_type'

同样对于那些驳斥TrueFalse作为元组返回的有用性的人,我给你举个例子:

>>> example = dict_all(iterable)
#if iterable is the example dictionary above
#the result would be
>>> print(example)
(False, 'comp_type')
#which means
#example[0] is a Truthy or Falsey for the value in the key
#they key is example[1]

Tags: thekey函数falsetrue元素hello字典
2条回答

编辑:这个答案是在您编辑它之前在原始dict_all函数的上下文中编写的。你知道吗

def dict_all(iterable):
    for i, e in enumerate(iterable):
        if not iterable[e]:
            return False, e
    return True

我有三点意见。你知道吗

首先,我不确定您是否意识到它,所以我要指出:您的dict_all查找falsy,而字典是其键上的iterable。你知道吗

>>> d = {1:2, 3:0}
>>> all(d)
True
>>> dict_all(d)
(False, 3)

其次,函数中的enumerate似乎毫无意义。考虑以下生成器表达式。你知道吗

>>> next(((False, key) for key, value in d.items() if not value), (True, None))
(False, 3)
>>> d = {1:2, 3:4}
>>> next(((False, key) for key, value in d.items() if not value), (True, None))
(True, None)

第三,得到实际的falsy值不是比仅仅得到False更有用吗?在这种情况下,在上面的表达式中使用(value, key)而不是(False, key)。你知道吗

编辑:因为您需要一个库函数,所以可以使用itertools.dropwhile删除带有truthy值的字典项。你知道吗

>>> from itertools import dropwhile    
>>> from operator import itemgetter
>>> 
>>> d = {1:2, 3:4, 5:0}
>>> next((dropwhile(itemgetter(1), d.items())), None)
>>> (5, 0)

这将为您提供一个(key,value)对和一个falsy值或None。你知道吗

您所需要做的就是迭代键值对,这样就可以测试值而不必再次引用原始映射,并且在值为false时返回键值。您还需要在返回类型中保持一致,并在两种情况下都返回一个元组:

def dict_all(mapping):
    for key, value in mapping.items():
        if not value:
            return False, key
    return True, None

注意最后一行的更改,您确实不希望为false返回一个tuple,为true返回一个boolean,因为这样您还必须测试返回类型,才能真正知道缺少了什么。你知道吗

对于这个问题没有“内置”函数,因为all()(和any())的设计纯粹是为了对这个问题产生一个yes或no的答案:iterable的所有元素都通过了测试吗。你知道吗

你问的是不同的问题;你的代码需要知道测试失败的第一个关键是什么。你知道吗

对于这个问题,我将使用^{} function,带有一个生成器表达式和一个默认值:

empty = next((key for key, value in mapping.items() if not value), None)
if empty is not None:
    raise CustomException('Missing value for {}'.format(empty))

在这里不需要返回TrueFalse;我们检测到在选取默认案例时没有键未通过测试,我们用empty is not None的测试替换了TrueFalse值。你知道吗

任何唯一的sentinel都可以;None是通常的选择,但是如果您的输入字典将None用作有效键,则可以使用object()

_sentinel = object()
empty = next((key for key, value in mapping.items() if not value), _sentinel)
if empty is not _sentinel:
    raise CustomException('Missing value for {}'.format(empty))

相关问题 更多 >