ens*_*are 103 python dictionary
我有一个字典,并希望删除所有有空值字符串的键.
metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
u'EXIF:CFAPattern2': u''}
Run Code Online (Sandbox Code Playgroud)
做这个的最好方式是什么?
Bre*_*arn 172
Python 2.X
dict((k, v) for k, v in metadata.iteritems() if v)
Run Code Online (Sandbox Code Playgroud)
Python 2.7 - 3.X
{k: v for k, v in metadata.items() if v is not None}
Run Code Online (Sandbox Code Playgroud)
请注意,您的所有键都有值.只是其中一些值是空字符串.在没有价值的字典中没有关键词; 如果它没有价值,它就不会出现在字典中.
小智 71
它可以比BrenBarn的解决方案更短(我认为更具可读性)
{k: v for k, v in metadata.items() if v}
Run Code Online (Sandbox Code Playgroud)
用Python 2.7.3测试.
nne*_*neo 20
如果你真的需要修改原始字典:
empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
del metadata[k]
Run Code Online (Sandbox Code Playgroud)
请注意,我们必须列出空键,因为我们无法在迭代时修改字典(您可能已经注意到了).这比创建一个全新的字典更便宜(内存方面),除非有很多条目具有空值.
Mah*_*emi 12
如果你想要一个功能齐全但简洁的方法来处理经常嵌套的实际数据结构,甚至可以包含循环,我建议从boltons实用程序包中查看重映射实用程序.
之后pip install boltons
或复制iterutils.py到您的项目,只是做:
from boltons.iterutils import remap
drop_falsey = lambda path, key, value: bool(value)
clean = remap(metadata, visit=drop_falsey)
Run Code Online (Sandbox Code Playgroud)
这个页面有更多的例子,包括使用Github API的更大对象的例子.
它是纯Python,因此它可以在任何地方使用,并且在Python 2.7和3.3+中进行了全面测试.最重要的是,我为这样的情况编写了它,所以如果你找到一个它无法处理的情况,你可以告诉我在这里解决它.
BrenBarn的解决方案是理想的(和pythonic,我可能会添加).这是另一个(fp)解决方案,但是:
from operator import itemgetter
dict(filter(itemgetter(1), metadata.items()))
Run Code Online (Sandbox Code Playgroud)
根据Ryan的解决方案,如果您还有列表和嵌套词典:
对于Python 2:
def remove_empty_from_dict(d):
if type(d) is dict:
return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
elif type(d) is list:
return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
else:
return d
Run Code Online (Sandbox Code Playgroud)
对于Python 3:
def remove_empty_from_dict(d):
if type(d) is dict:
return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
elif type(d) is list:
return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
else:
return d
Run Code Online (Sandbox Code Playgroud)
如果你有一个嵌套字典,并且你希望它甚至可以用于空子元素,你可以使用BrenBarn建议的递归变体:
def scrub_dict(d):
if type(d) is dict:
return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
else:
return d
Run Code Online (Sandbox Code Playgroud)
### example01 -------------------
mydict = { "alpha":0,
"bravo":"0",
"charlie":"three",
"delta":[],
"echo":False,
"foxy":"False",
"golf":"",
"hotel":" ",
}
newdict = dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(vdata) ])
print newdict
### result01 -------------------
result01 ='''
{'foxy': 'False', 'charlie': 'three', 'bravo': '0'}
'''
Run Code Online (Sandbox Code Playgroud)
### example02 -------------------
mydict = { "alpha":0,
"bravo":"0",
"charlie":"three",
"delta":[],
"echo":False,
"foxy":"False",
"golf":"",
"hotel":" ",
}
newdict = dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(str(vdata).strip()) ])
print newdict
### result02 -------------------
result02 ='''
{'alpha': 0,
'bravo': '0',
'charlie': 'three',
'delta': [],
'echo': False,
'foxy': 'False'
}
'''
Run Code Online (Sandbox Code Playgroud)
基于patriciasz和nneonneo的答案,并考虑到您可能想要删除仅包含某些虚假内容(例如''
)但不包含其他内容(例如0
)的密钥的可能性,或者您甚至可能想包含一些真实的内容(例如'SPAM'
) ,那么你可以制作一个非常具体的命中列表:
unwanted = ['', u'', None, False, [], 'SPAM']
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不太有效,因为例如0 in unwanted
评估为True
. 我们需要区分0
其他虚假的东西,所以我们必须使用is
:
any([0 is i for i in unwanted])
Run Code Online (Sandbox Code Playgroud)
...评估为False
.
现在用它来处理del
不需要的东西:
unwanted_keys = [k for k, v in metadata.items() if any([v is i for i in unwanted])]
for k in unwanted_keys: del metadata[k]
Run Code Online (Sandbox Code Playgroud)
如果你想要一个新的字典,而不是metadata
就地修改:
newdict = {k: v for k, v in metadata.items() if not any([v is i for i in unwanted])}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
79754 次 |
最近记录: |