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(您的口述)",即設置交集(&;),而不是設置差(-)。假設密鑰是不需要的密鑰列表。
稍微優雅一點的聽寫理解:
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以只包含某些键?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安徽信息技术初中会考上机考试模拟_中学信
- 下一篇: centos 日志审计_Linux\Ce