Efficient way to remove keys with empty strings from a dict
我有一个dict,想删除所有有空值字符串的键。
1 2 | metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)', u'EXIF:CFAPattern2': u''} |
最好的方法是什么?
Python 2.x。 </P >
1 | dict((k, v) for k, v in metadata.iteritems() if v) |
Python 2.7×3。 </P >
1 | {k: v for k, v in metadata.items() if v is not None} |
注意你的钥匙,是所有有价值的。它的正是那一些这些值的字符串是空的。没有这样的东西作为一个关键的字典中没有值;如果它不有一个值,它不可能要问的字典。 </P >
它可以brenbarn山羊甚至比短的溶液(和更多的我想readable) </P >
1 | {k: v for k, v in metadata.items() if v} |
2.7.3用Python测试。 </P >
如果你真的要修改的原始字典: </P >
1 2 3 | empty_keys = [k for k,v in metadata.iteritems() if not v] for k in empty_keys: del metadata[k] |
注意,我们要做一个狡猾的空的钥匙,因为我们不能修改字典随迭代通(作为你的计算机可能有noticed)。这是无聊的扩张(记忆之比(A)创造全新的字典,但是,除非这是一个很多entries与空值。 </P >
如果你想要A,功能齐全,succinct方法对真实世界的行为,这是经常的数据结构和套式,甚至可以包含的周期,在recommend看着《remap型从博尔顿型包。 </P >
售后copying iterutils.py
1 2 3 4 | from boltons.iterutils import remap drop_falsey = lambda path, key, value: bool(value) clean = remap(metadata, visit=drop_falsey) |
本页有许多更多的例子,包括所有的工作与多larger对象从GitHub的API。 </P >
它的纯Python,所以它everywhere冰厂,全面测试和Python 2.7分和3.3 +。所有的野兽,在它的wrote exactly案件,所以呢,如果你找到一个实例的计算机不对付,你可以修复它的错误我到这里吧。 </P >
基于瑞安的溶液,如果你也有和套式词典列表: </P >
方法2:Python </P >
1 2 3 4 5 6 7 | 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 |
因为Python 3: </P >
1 2 3 4 5 6 7 | 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 |
brenbarn的溶液和冰的理想语言,可能会增加)。这里的另一个冰(FP)溶液,然而: </P >
1 2 | from operator import itemgetter dict(filter(itemgetter(1), metadata.items())) |
如果你有一套式词典,和你想要的文件到工作,甚至为空的子元素,你可以使用递归brenbarn变型A学院的建议: </P >
1 2 3 4 5 | 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 |
建筑的patriciasz解答的虔诚和nneonneo,和会计的可能性,你可能会想删除的钥匙,那只falsy有某些事情(例如
1 | unwanted = ['', u'', None, False, [], 'SPAM'] |
不幸的是,这不quite因为工作的关系,例如
1 | any([0 is i for i in unwanted]) |
...evaluates到
现在使用它的unwanted
1 2 | 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] |
如果你想一个新的字典,而不是大学modifying
1 | newdict = {k: v for k, v in metadata.items() if not any([v is i for i in unwanted])} |
快速应答(TL;博士) example01
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ### 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'} ''' |
详细的回答 问题
- 目的:2.x Python
- 场景:开发商的意愿修改A blank values to排除词典
- 又名remove空值从一本字典
- 又名delete键with blank values
- 又名滤波器字典的非空白值在每一对密钥值
溶液
- example01使用Python列表理解语法和简单的条件去解除"空"的价值观
pitfalls
- example01只operates在线杂志的一份正本(美国能源部词典标注修改输入的地方)
- example01可能产生意想不到的结果depending通什么开发商均值村"空"
- 美国能源部的开发商均对保持falsy值,是吗?
- 如果值是在字典中注释的字符串中确保的是,开发商可能会有意想不到的数据槽。
- result01演那只三关键值是保持对从原集
另以
- example02 helps pitfalls交易与潜力
- 冰的方法对使用一个更精确的定义,"空"村的变化的条件。
- 在这里我们只想滤波器超时值是评价到空白的字符串。
- 让我们也使用.strip()对滤波器的超时值是只读的consist大学的空白。
example02
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ### 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' } ''' |
也见
- 战略的理解
- falsy
- 检查字符串为空
- 在原来的地方modifying词典
- 字典的理解
- pitfalls部检查为空字符串
因为Python 3 </P >
1 | dict((k, v) for k, v in metadata.items() if v) |
我阅读了这篇文章中的所有回复,有些还提到了这篇文章:用递归函数删除嵌套字典中的空dict
我最初在这里使用的解决方案非常有效:
尝试1:太热(无法执行或证明未来):
1 2 3 4 5 | 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 |
但在python 2.7世界中出现了一些性能和兼容性问题:
尝试2:太冷(缺少记忆):
1 2 3 4 5 6 7 8 | def scrub_dict(d): new_dict = {} for k, v in d.items(): if isinstance(v,dict): v = scrub_dict(v) if not v in (u'', None, {}): new_dict[k] = v return new_dict |
呸!这不是递归的,完全不是memoizant。
尝试3:刚刚好(目前为止):
1 2 3 4 5 6 7 8 | def scrub_dict(d): new_dict = {} for k, v in d.items(): if isinstance(v,dict): v = scrub_dict(v) if not v in (u'', None, {}): new_dict[k] = v return new_dict |
上面提到的一些方法忽略是否存在任何整数,并且浮点值为0&0.0
如果有人想避免上述情况,可以使用以下代码(从嵌套字典和嵌套列表中删除空字符串和无值):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def remove_empty_from_dict(d): if type(d) is dict: _temp = {} for k,v in d.items(): if v == None or v =="": pass elif type(v) is int or type(v) is float: _temp[k] = remove_empty_from_dict(v) elif (v or remove_empty_from_dict(v)): _temp[k] = remove_empty_from_dict(v) return _temp elif type(d) is list: return [remove_empty_from_dict(v) for v in d if( (str(v).strip() or str(remove_empty_from_dict(v)).strip()) and (v != None or remove_empty_from_dict(v) != None))] else: return d |
如果您使用的是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import pandas as pd d = dict.fromkeys(['a', 'b', 'c', 'd']) d['b'] = 'not null' d['c'] = '' # empty string print(d) # convert `dict` to `Series` and replace any blank strings with `None`; # use the `.dropna()` method and # then convert back to a `dict` d_ = pd.Series(d).replace('', None).dropna().to_dict() print(d_) |
另一种方法是使用字典理解。这应该与
1 2 3 4 5 | result = { key: value for key, value in {"foo":"bar","lorem": None}.items() if value } |
一些基准:1。列表理解重新创建dict
1 2 3 | In [7]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None ...: dic = {k: v for k, v in dic.items() if v is not None} 1000000 loops, best of 7: 375 ns per loop |
2。列表理解使用dict()重新创建dict
1 2 3 | In [8]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None ...: dic = dict((k, v) for k, v in dic.items() if v is not None) 1000000 loops, best of 7: 681 ns per loop |
三。如果v为无,则循环并删除键
1 2 3 4 5 6 | In [10]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None ...: for k, v in dic.items(): ...: if v is None: ...: del dic[k] ...: 10000000 loops, best of 7: 160 ns per loop |
所以loop和delete是最快的,在160ns时,列表理解的速度是在375ns时的一半,调用
将3包装成一个函数,使它再次回到275ns左右。对我来说,pypy的速度是neet python的两倍。