欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > python >内容正文

python

dict过滤 python_关于python:过滤dict以只包含某些键?

发布时间:2025/3/19 python 44 豆豆
生活随笔 收集整理的这篇文章主要介绍了 dict过滤 python_关于python:过滤dict以只包含某些键? 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

我有一个dict,有很多条目。我只对其中一些感兴趣。有没有一种简单的方法可以把其他的修剪掉?

构建新的dict:

dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }

使用字典理解。

如果您使用的版本缺少它们(如python 2.6和更早版本),请使用dict((your_key, old_dict[your_key]) for ...)。这是一样的,虽然更丑。

请注意,与Jnnnn的版本不同,这对于任何大小的old_dict都具有稳定的性能(仅取决于您的密钥数量)。无论是速度还是记忆。因为这是一个生成器表达式,所以它一次只处理一个项目,而不查看旧字典的所有项目。

移除所有东西:

unwanted = set(keys) - set(your_dict)

for unwanted_key in unwanted: del your_dict[unwanted_key]

不知道你也能听写理解…漂亮!这是一个很好的解决方案。

"使用字典理解,如果使用缺少字典的版本"==版本<=2.6

如果其中一个文件管理器键不在旧的_dict中,则引发keyError。如果在d_中有k,则建议在filter中为k执行k:d[k]

@是的,如果这是需求的一部分,你需要做些什么。无论是静默地删除键、添加默认值还是其他什么,都取决于您正在做什么;在许多用例中,您的方法是错误的。还有很多地方,old_dict中缺少的键指示其他地方存在错误,在这种情况下,我非常喜欢错误,而不是默许错误的结果。

@Delnan,还有"if k in d"的加法,如果d很大,会减慢速度,我只是觉得值得一提。

@不是的,字典查找是O(1)。

@德尔南,对吧-当然

如果您不想在密钥不存在的情况下抛出错误,则可以这样操作:dict_you want=dict((key,old_dict[key])for key in[k for k in your_keys if k in old_dict])

很好的解释,特别是O(1)

NIT:字典是散列图,所以正常情况下是O(1)。最坏(极不可能)的情况是O(N),但取决于哈希冲突的可能性。你需要一本天文大字典,或者一个非常粗糙的哈希算法来开始发现这是一个问题。stackoverflow.com/a/1963514/1335793

我认为这应该是"不需要的=集(键)&set(您的口述)",即设置交集(&amp;),而不是设置差(-)。假设密钥是不需要的密钥列表。

稍微优雅一点的听写理解:

foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}

投票赞成的我在考虑增加一个类似的答案。不过出于好奇,为什么在dict.items()中,k:v表示k,v,而不是在dict中,k:dict[k]表示k…有性能差异吗?

回答了我自己的问题。在dict…中,k的k:dict[k]速度大约快20-25%,至少在python 2.7.6中,字典中有26个项目(timeit(…,setup="d=chr(x+97):x+1代表x in range(26)"),这取决于筛选出的项目数(筛选出辅音键比筛选出元音键快,因为您查找的项目较少)。随着字典大小的增长,性能上的差异可能会变得不那么显著。

如果使用mydict.iteritems(),性能可能相同。.items()创建另一个列表。

下面是Python2.6中的一个示例:

>>> a = {1:1, 2:2, 3:3}

>>> dict((key,value) for key, value in a.iteritems() if key == 1)

{1: 1}

过滤部分是if语句。

如果您只想选择非常多的键中的一些,这个方法比Delnan的答案慢。

但我想我可能会用if key in ('x','y','z')。

如果你已经知道你想要哪把钥匙,用德尔南的答案。如果需要用if语句测试每个键,请使用ransford的答案。

这个解决方案还有一个优点。如果字典是从昂贵的函数调用(即a/old_dict是函数调用)返回的,则此解决方案只调用一次函数。在命令式环境中,将函数返回的字典存储在变量中并不重要,但在函数式环境(例如lambda中)中,这是关键观察。

您可以使用我的Funcy库中的Project函数来完成此操作:

from funcy import project

small_dict = project(big_dict, keys)

还可以看一下select_键。

这一个线性lambda应该工作:

dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])

下面是一个例子:

my_dict = {"a":1,"b":2,"c":3,"d":4}

wanted_keys = ("c","d")

# run it

In [10]: dictfilt(my_dict, wanted_keys)

Out[10]: {'c': 3, 'd': 4}

它是一个基本的列表理解,迭代您的dict键(x中的i),并输出一个tuple(key,value)对列表,前提是该键位于您想要的key list(y)中。dict()将整个内容包装成dict对象输出。

应该使用set作为wanted_keys,否则看起来不错。

如果我的原始字典包含列表而不是值,这将给我一个空白字典。有什么解决办法吗?

@弗朗西斯科,你能举个例子吗?如果我运行:dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['‌​oiejf','iejf']}, ('x','z')),它会按预期返回{'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}。

我试了一下:dict={'0':[1,3], '1':[0,2,4], '2':[1,4]},结果是{},我认为这是一个空白的口述。

有一件事,"dict"是一个保留字,所以你不应该用它来命名dict。你想拔出的钥匙是什么?如果我运行:foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2')),我得到:{'0': [1, 3], '2': [1, 4]},这是预期的结果。

鉴于您的原始词典orig和您对keys感兴趣的条目集:

filtered = dict(zip(keys, [orig[k] for k in keys]))

这并不如Delnan的答案好,但应该适用于感兴趣的每个Python版本。但是,它对于原始字典中存在的keys的每个元素都是脆弱的。

嗯,这基本上是我听写理解的"元组生成器版本"的热切版本。确实非常兼容,尽管2005年春季2.4版中引入了生成器表达式——说真的,有人还在使用它吗?

我不反对;2.3真的不应该再存在了。但是,作为对2.3用法的过时调查:moinmo.in/polluaboutrequireingpython24短版:rhel4,sles9,随OS X 10.4一起提供

代码1:

dict = { key: key * 10 for key in range(0, 100) }

d1 = {}

for key, value in dict.items():

if key % 2 == 0:

d1[key] = value

代码2:

dict = { key: key * 10 for key in range(0, 100) }

d2 = {key: value for key, value in dict.items() if key % 2 == 0}

代码3:

dict = { key: key * 10 for key in range(0, 100) }

d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}

所有代码性能的片段都是用timeit来度量的,使用number=1000,并且为每段代码收集1000次。

对于python3.6,三种过滤dict键的性能几乎相同。对于Python2.7,代码3稍微快一点。

只是好奇,你是从Python那里编出来的?

Matplotlib是一个很好的猜测:)

R中的ggplot2-tidyverse的一部分

此功能将实现以下功能:

def include_keys(dictionary, keys):

"""Filters a dict by only including certain keys."""

key_set = set(keys) & set(dictionary.keys())

return {key: dictionary[key] for key in key_set}

就像Delnan的版本一样,这个版本使用字典理解,并且对于大型字典具有稳定的性能(仅取决于您允许的键数,而不是字典中的键总数)。

和Myggan的版本一样,这个版本允许您的键列表包含字典中可能不存在的键。

作为一个额外的好处,这里是相反的,您可以通过排除原始文件中的某些键来创建字典:

def exclude_keys(dictionary, keys):

"""Filters a dict by excluding certain keys."""

key_set = set(dictionary.keys()) - set(keys)

return {key: dictionary[key] for key in key_set}

请注意,与Delnan的版本不同,操作没有在适当的位置完成,因此性能与字典中的键数有关。但是,这样做的好处是函数不会修改提供的字典。

编辑:添加了一个单独的函数,用于从dict中排除某些键。

你应该允许keys以任何一种不可更改的方式,像set接受的那样。

啊,打得好,谢谢你指正。我会更新的。

我想知道你是否有两个更好的功能。如果你问10个人,"invert是否意味着保留了keys的论点,或者拒绝了keys的论点?"他们中有多少人会同意?

嗯,说得对。让我看看。

更新。告诉我你的想法。

如果输入dict中有列表而不是值,这似乎不起作用。在这种情况下,你会得到一个无效的口述。有什么解决办法吗?

基于德尔南接受的答案。

如果你想要的钥匙不在旧的口述里怎么办?Delnan解决方案将抛出一个可以捕获的keyError异常。如果这不是你需要的,也许你想:

只包括在旧的口述和你想要的一套钥匙中都会兴奋的钥匙。

old_dict = {'name':"Foobar", 'baz':42}

wanted_keys = ['name', 'age']

new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}

>>> new_dict

{'name': 'Foobar'}

有一个未在旧字典中设置的键的默认值。

default = None

new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}

>>> new_dict

{'age': None, 'name': 'Foobar'}

你也可以做{k: old_dict.get(k, default) for k in ...}。

另一种选择:

content = dict(k1='foo', k2='nope', k3='bar')

selection = ['k1', 'k3']

filtered = filter(lambda i: i[0] in selection, content.items())

但是,您会得到由filter()返回的list(python2)或迭代器(python3),而不是dict。

把filtered包在dict里,你就能找到字典了!

简短形式:

[s.pop(k) for k in list(s.keys()) if k not in keep]

正如大多数答案所建议的那样,为了保持简洁,我们必须创建一个重复的对象,无论是list还是dict。这将创建一个丢弃的list,但会删除原始dict中的密钥。

总结

以上是生活随笔为你收集整理的dict过滤 python_关于python:过滤dict以只包含某些键?的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。