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}

生成的 dict 应如下所示:

new = {"name":"yass"}
4

5 回答 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}
于 2013-05-22T14:01:31.517 回答
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'}

白名单版本(使用 set intersection):

>>> whitelist = {'city', 'name', 'region', 'zipcode', 'phone', 'address'}
>>> {k: dict1[k] for k in dict1.viewkeys() & whitelist if dict1[k]}
{'name': 'yass'}
于 2013-05-22T14:04:59.963 回答
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]}
于 2013-05-22T14:30:08.347 回答
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'}
于 2013-05-22T14:03:58.690 回答
1

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

new = {k:dict1[k] for k in dict1 if k not in blacklist and dict1[k]}
于 2013-05-22T14:07:25.037 回答