检查字典中的值是否已定义/长度为零的最 Pythonic 方法

发布于 2024-12-10 06:27:04 字数 926 浏览 0 评论 0原文

假设我有一本字典,我想检查键是否映射到非空值。实现此目的的一种方法是 len 函数:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if len(mydict["key"]) > 0 else "False"  # prints true
print "True" if len(mydict["emptykey"]) > 0 else "False"  # prints false

但是,我们可以依赖 Python 的语义,以及如果定义了一个对象,它如何计算为 true 并省略 len 调用:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if mydict["key"] else "False"  # prints true
print "True" if mydict["emptykey"] else "False"  # prints false

但是,我不确定哪个更 Pythonic 。第一个感觉“显式优于隐式”,而第二个感觉“简单优于复杂”。

我还想知道省略 len 调用是否会困扰我,因为我正在使用的字典不一定包含字符串,但可能包含其他可长度类型(列表、集合等)。 OTOH,在前者(使用 len 调用)中,如果 None 被存储为值,则代码将崩溃,而非 len 版本将按预期工作(将评估为 false)。

哪个版本更安全、更Pythonic?

编辑:澄清假设:我知道密钥在字典中,并且我知道值将是可调整的。我也无法避免零长度值进入字典。

编辑#2:似乎人们没有抓住我问题的重点。我并不是想确定检查字典中是否存在键的最 Pythonic/最安全的方法,而是尝试检查值的长度是否为零

Say I have a dictionary, and I want to check if a key is mapped to a nonempty value. One way of doing this would be the len function:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if len(mydict["key"]) > 0 else "False"  # prints true
print "True" if len(mydict["emptykey"]) > 0 else "False"  # prints false

However, one can rely on the semantics of Python and how if an object is defined it evaluates to true and leave out the len call:

mydict = {"key" : "value", "emptykey" : ""}
print "True" if mydict["key"] else "False"  # prints true
print "True" if mydict["emptykey"] else "False"  # prints false

However, I'm not sure which is more Pythonic. The first feels "explicit is better than implicit", however the second feels "simple is better than complex".

I also wonder if the leaving out the len call could bite me as the dict I'm working with doesn't necessarily contain strings, but could contain other len-able types (lists, sets, etc). OTOH, in the former (with the len call) if None gets stored as a value the code will blow up, whereas the non-len version will work as expected (will eval to false).

Which version is safer and more Pythonic?

Edit: clarifying assumptions: I know the key is in the dictionary, and I know values will be len-able. I also cannot avoid having zero-length values enter the dictionary.

Edit #2: It seems like people are missing the point of my question. I'm not trying to determine the most Pythonic/safest way of checking if a key is present in a dictionary, I'm trying to check if a value has zero length or not

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

远山浅 2024-12-17 06:27:04

如果您知道键在字典中,请使用

if mydict["key"]:
    ...

它,它很简单,易于阅读,并且表示“如果与“键”相关的值的计算结果为True,则执行某些操作”。需要了解的重要一点是,容器类型(dict、list、tuple、str 等)仅在其 len 大于 0 时才计算为 True

它还会引发如果违反了密钥位于 mydict 中的前提,则会出现 KeyError

所有这些都使它变得Pythonic。

If you know the key is in the dictionary, use

if mydict["key"]:
    ...

It is simple, easy to read, and says, "if the value tied to 'key' evaluates to True, do something". The important tidbit to know is that container types (dict, list, tuple, str, etc) only evaluate to True if their len is greater than 0.

It will also raise a KeyError if your premise that a key is in mydict is violated.

All this makes it Pythonic.

可爱暴击 2024-12-17 06:27:04
print (bool(mydict.get('key')))

或者,在 if 语句中:

print ('True' if mydict.get('key') else 'False')

如果您的值不存在是一个错误情况(即您希望它存在),您应该选择解决方案 #2,即

print ('True' if mydict['key'] else 'False')

允许 mydict['key'] 选择最有效的空定义。对于某些对象(例如簇中的对象),确定实际长度是一个相当复杂的操作,而确定对象是否为空则很简单。

您还可以与 '' 进行比较,即 mydict['key'] == '',以使您的表达更加清晰。使用 len 可以,但不够直观。

总之,将其留给测试对象来定义它是否为空,并将其转换为 bool 。

print (bool(mydict.get('key')))

or, in an if statement:

print ('True' if mydict.get('key') else 'False')

If you the value not being present is an error case (i.e. you expect it to be there), you should choose solution #2, i.e.

print ('True' if mydict['key'] else 'False')

That allows mydict['key'] to choose the most efficient definition for being empty. For some objects (such as ones in clusters), determining the actual length is a fairly complicated operation, whereas it's simple to determine whether the object is empty or not.

You could also compare to '', i.e. mydict['key'] == '', to make your expression abundantly clear. Using len works, but is not as intuitive.

In summary, leave it to the tested object to define whether it's empty or not and just cast it to bool.

卷耳 2024-12-17 06:27:04

标题和第一句实际上表达了两个略有不同的问题。

对于标题问题

检查字典中的值是否已定义的最 Pythonic 方法

我会选择

"key" in mydict

和 对于第二个问题

假设我有一本字典,我想检查键是否映射到非空值。

我会选择

"key" in mydict and bool(mydict["key"])

第一部分检查 mydict 中是否存在“key”,第二部分对除 False、None、空字符串、空字典、空之外的“key”的所有值返回 true列表和 0。

The title and the first sentence actually express two slightly different questions.

For the title question

The most Pythonic way of checking if a value in a dictionary is defined

I'd go with

"key" in mydict

and for the second question

Say I have a dictionary, and I want to check if a key is mapped to a nonempty value.

I'd go with

"key" in mydict and bool(mydict["key"])

The first part of which checks to see whether "key" is present in mydict and the second part returns true for all values of "key" other then False, None, the empty string, the empty dictionary, the empty list and 0.

白衬杉格子梦 2024-12-17 06:27:04

我会使用第一个选项的变体:

>>> mydict = {"key" : "value", "emptykey" : ""}
>>> print bool(mydict["key"])
True
>>> print bool(mydict["emptykey"])
False

任何提供 __len__ 的类都可以直接转换为布尔值(请参阅真值测试),因此 bool(container) 相当于bool(len(容器))。长度 0 将成为布尔值 False,而所有其他长度将为 True。你永远不会有负长度的对象。此外,布尔值 TrueFalse 可以通过 print 直接打印,因此您不需要条件。

I'd use a variation of the first option:

>>> mydict = {"key" : "value", "emptykey" : ""}
>>> print bool(mydict["key"])
True
>>> print bool(mydict["emptykey"])
False

Any class that provides __len__ can be converted into a boolean directly (see Truth Value Testing), so bool(container) is the equivalent of bool(len(container)). A length of 0 will become the boolean False while all other lengths will be True. You'll never have a negative length object. Also, the booleans True and False can be printed directly via print, so you don't need the conditional.

脱离于你 2024-12-17 06:27:04

来自此处

在布尔运算的上下文中,以及当控制流语句使用表达式时,以下值将被解释为 false:FalseNone、数字零所有类型以及空字符串和容器(包括字符串、元组、列表、字典、集合和冻结集合)。所有其他值均解释为 true。

我认为可以肯定地说,直接评估它是最好的选择 - 尽管正如 @phihag 所说,使用 get 相反,因为它会保护您免受 KeyError 的影响。

From here:

In the context of Boolean operations, and also when expressions are used by control flow statements, the following values are interpreted as false: False, None, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true.

I think it's safe to say that directly evaluating it is your best option - although, as @phihag said, it's safer to use get instead, as it will protect you from a KeyError.

倒带 2024-12-17 06:27:04

在你的两个例子中,我更喜欢第二个。

但是,我建议不要存储空密钥。另外,defaultdict 在这里也可以很好地工作:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True

如果必须存储空键,则不需要字符串值 "True""False"。只需这样做:

print bool(mydict[key])

Of your two examples I prefer the second.

However, I advise against storing the empty keys. Also a defaultdict would work well here:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d[1].append(1)
>>> 1 in d
True

If you must store empty keys you don't need the string values "True" and "False". Just do this:

print bool(mydict[key])
情归归情 2024-12-17 06:27:04

您可以通过以下方式简单地检查字典中的任何值是否为零长度:

# To get keys which having zero length value:
keys_list = [key for key,val in mydict.items() if not val]


# To check whether the dict has any zero length value in it (returns True or False):
any_empty_vals = bool(len(['' for x in data_dict.values() if not x]))

You can simply check that any value in the dict is zero length or not by :

# To get keys which having zero length value:
keys_list = [key for key,val in mydict.items() if not val]


# To check whether the dict has any zero length value in it (returns True or False):
any_empty_vals = bool(len(['' for x in data_dict.values() if not x]))
破晓 2024-12-17 06:27:04

因为我来这里是为了知道我们是否可以检查字典键是否存在,所以答案是:

if mydict.get(key,0):
    ---

并且键的长度> 。 0,答案已经由@Ethan Furman提供

if mydict[key]:
    ---

Since I came here to know whether we can check the dictionary key is present or not for those the answer is:

if mydict.get(key,0):
    ---

and for the length of the key > 0, the answer is already provided by @Ethan Furman

if mydict[key]:
    ---
哆兒滾 2024-12-17 06:27:04
mydict = {"key" : "value", "emptykey" : ""}

if not mydict["emptykey"]:
   print("empty value")
else:
   print("value of emptykey",mydict["emptykey"])

输出

empty value
mydict = {"key" : "value", "emptykey" : ""}

if not mydict["emptykey"]:
   print("empty value")
else:
   print("value of emptykey",mydict["emptykey"])

Output

empty value
留蓝 2024-12-17 06:27:04

最Pythonic的方法是不定义未定义的值(尽管这是否可用取决于你使用它的目的)并使用in

mydict = {"key" : "value"}
print "True" if "key" in mydict else "False"  # prints true
print "True" if "emptykey" in mydict else "False"  # prints false

否则,你有三个选择:

  1. 使用mydict.get。如果键可能在或不在字典中,您应该使用它。
  2. 使用mydict[key]。如果您确定所需的密钥在字典中,则应该使用此选项。
  3. 使用 len(mydict[key]) > 0 。仅当值定义了 __len__ 时才有效。通常,容器值的真值无论如何都取决于 __len__,因此以上是更可取的。

The most Pythonic way would be to not define the undefined value (although whether this is usable depends on what you're using it for) and use in:

mydict = {"key" : "value"}
print "True" if "key" in mydict else "False"  # prints true
print "True" if "emptykey" in mydict else "False"  # prints false

Otherwise, you have three options:

  1. Use mydict.get. You should use this if the key might or might not be in the dictionary.
  2. Use mydict[key]. You should use this if you are certain the key you want is in the dict.
  3. Use len(mydict[key]) > 0. This only works if the value has __len__ defined. Usually, the truth value of a container value depends on the __len__ anyway, so the above are preferable.
不顾 2024-12-17 06:27:04

解析函数的 kwargs 时,字典可能包含值为 None 的键,并且您需要知道传入的函数参数是否等于 None,或者只是未定义。这是消除歧义的最简单方法:

def myfunct(**kwargs):
    if 'thiskey' not in kwargs:
        # this means that 'thiskey' was never passed into myfunct().
        kwargs['thiskey'] = <default value>
    else:
        # you can define the defaults differently; 
        # if was defined as None, keep it set to None this way.
        kwargs['thiskey'] = kwargs.get('thiskey', None)
        # otherwise, any defined value passes through.
    # do stuff...

When parsing a function's kwargs, it does make sense why the dictionary might contain a key whose value is None, and that you'd need to know whether that function's argument was passed in equal to None, or just not defined. Here's the simplest way to disabiguate:

def myfunct(**kwargs):
    if 'thiskey' not in kwargs:
        # this means that 'thiskey' was never passed into myfunct().
        kwargs['thiskey'] = <default value>
    else:
        # you can define the defaults differently; 
        # if was defined as None, keep it set to None this way.
        kwargs['thiskey'] = kwargs.get('thiskey', None)
        # otherwise, any defined value passes through.
    # do stuff...
不疑不惑不回忆 2024-12-17 06:27:04

我想知道哪个键丢失了,这样我就可以修复它(例如在数据库中),但我也不想为字典中的每个键执行 if 语句!这是我的代码:

def do_sth_with_data(data):

        assert isinstance(data, dict)
      
        expected_data_keys = {
            "id",
            "title",
            "date",
            "key4",
            "key5",
            "key6"

        }

        empty_keys = [key for key in expected_data_keys if not data.get(key)]
        if empty_keys:
            raise ValueError(f"{empty_keys} keys are not provided or are empty!")

如果您还想区分 key 缺失和 key 的值缺失,您可以添加这样的脚本(根据您的需要):

assert expected_data_keys.issubset(set(data.keys()))

请记住,如果键不存在或键存在但相应的值为空(例如[]{}“”

I wanted to know which key is missing, so I could go fix it (in the db for example), but I also didn't want to do an if statement for each key in my dictionary! Here is my code:

def do_sth_with_data(data):

        assert isinstance(data, dict)
      
        expected_data_keys = {
            "id",
            "title",
            "date",
            "key4",
            "key5",
            "key6"

        }

        empty_keys = [key for key in expected_data_keys if not data.get(key)]
        if empty_keys:
            raise ValueError(f"{empty_keys} keys are not provided or are empty!")

If you also want to distinguish between key missing and value for the key is missing, you could add a script like this (change the code logic based on your need):

assert expected_data_keys.issubset(set(data.keys()))

Remember that data.get(key) will return None by default if either the key doesn't exist or the key exists but the corresponding value is empty (e.g. [], {}, None, "")

行至春深 2024-12-17 06:27:04

你的初始条件不是 Pythonic 的。为什么要存储一个空值的键?您可以删除该密钥而不是将其设置为“无”吗?

Pythonic 方法是使用 if key indictionary 检查键是否存在,而不是检查非空值。

Your initial conditions are not Pythonic. Why are you storing a key with an empty value? Can you delete the key instead of setting it to None?

The Pythonic way is to check key existence with if key in dictionary, not checking for a non-empty value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文