检查字典键是否为空值

6

我有以下字典

dict1 ={"city":"","name":"yass","region":"","zipcode":"",
       "phone":"","address":"","tehsil":"", "planet":"mars"}

我正在尝试创建一个基于dict1的新字典,但是:
  1. 它将不包含空字符串键。
  2. 它将不包含我不想包括的那些键。
我已经能够满足要求2,但在要求1方面遇到了问题。以下是我的代码:
dict1 ={"city":"","name":"yass","region":"","zipcode":"",
   "phone":"","address":"","tehsil":"", "planet":"mars"}

blacklist = set(("planet","tehsil"))    
new = {k:dict1[k] for k in dict1 if k not in blacklist} 

这将给我一个不带"tehsil"和"planet"键的字典。我也尝试了以下方法,但它没有起作用。

new = {k:dict1[k] for k in dict1 if k not in blacklist and dict1[k] is not None}

生成的字典应该像下面这样:
new = {"name":"yass"}
5个回答

5
这是一个白名单版本:
>>> dict1 ={"city":"","name":"yass","region":"","zipcode":"",
       "phone":"","address":"","tehsil":"", "planet":"mars"}
>>> whitelist = ["city","name","planet"]
>>> dict2 = dict( (k,v) for k, v in dict1.items() if v and k in whitelist )
>>> dict2
{'planet': 'mars', 'name': 'yass'}

黑名单版本:

>>> blacklist = set(("planet","tehsil"))
>>> dict2 = dict( (k,v) for k, v in dict1.items() if v and k not in blacklist )
>>> dict2
{'name': 'yass'}

两者本质上是相同的,只是一个使用了 not in 而另一个使用了 in。如果你的Python版本支持它,可以这样做:

>>> dict2 = {k: v for k, v in dict1.items() if v and k in whitelist}

并且

>>> dict2 = {k: v for k, v in dict1.items() if v and k not in blacklist}

可以使用字典推导式 {k: v for k, v ....},即使它不兼容Python 2.6,但我们知道OP正在使用2.7+。 - jamylak

4
这可能是最快的方法来完成它(使用set difference):
>>> dict1 = {"city":"","name":"yass","region":"","zipcode":"",
       "phone":"","address":"","tehsil":"", "planet":"mars"}
>>> blacklist = {"planet","tehsil"}
>>> {k: dict1[k] for k in dict1.viewkeys() - blacklist if dict1[k]}
{'name': 'yass'}

白名单版本(使用集合交集):

>>> whitelist = {'city', 'name', 'region', 'zipcode', 'phone', 'address'}
>>> {k: dict1[k] for k in dict1.viewkeys() & whitelist if dict1[k]}
{'name': 'yass'}

谢谢。如果我只想要非空白名单值,该怎么办? - hjelpmig
@yasra002 也添加了这个。 - jamylak
我用的那个选项和你用的那个选项,哪一个更好呢?我对Python还不是很熟悉,所以不确定哪个是最好的。 - hjelpmig
1
@yasra002 在 Python <= 2.6 版本中,人们只会编写像 set((1, 2, 3)) 这样的集合,因为当时还没有集合字面量({1, 2, 3})。你现在所做的是创建一个元组并将其传递给一个集合构造函数。现在我们有了集合字面量,所以你应该使用它们 ;) - jamylak

1
你正在正确的方向上。请考虑以下内容:
Python 2.7.3 (default, Apr 24 2012, 00:00:54) 
[GCC 4.7.0 20120414 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> dict1 ={"city":"","name":"yass","region":"","zipcode":"",
...    "phone":"","address":"","tehsil":"", "planet":"mars"}
>>> 
>>> def isgood(undesired, key, val): return key not in undesired and key and val
... 
>>> dict([x for x in dict1.items() if isgood(["planet", "tehsil"], *x)])
{'name': 'yass'}

@lshpeck 但这只适用于固定长度的字典,如果我错了请纠正我。 - hjelpmig
2
不,这对于任何长度的字典都适用。(在我的编辑之前和之后都是如此) - Ishpeck

1

只需测试 dict1[k] 的真值(而不是 is None)即可。

new = {k:dict1[k] for k in dict1 if k not in blacklist and dict1[k]}

1

测试一个值是否不是空字符串时,不要使用 is not None

空字符串被视为 False,而任何非空字符串都被视为 True。因此,您可以直接测试它,并从表达式中简单地删除 is not None

new = {k:dict1[k] for k in dict1 if k not in blacklist and dict1[k]}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接