2012-08-16 85 views
0

由於數據結構如下:Python的字典重組

out = { 
    'foo': { 'public':{}, 'private':{}, 'other':{} }, 
    'bar': { 'public':{}, 'private':{}, 'other':{} } 
} 

我試圖出底部結構的部分來創建一個新dict。我對此的用途是迴應所有數據的請求,但標記爲private除外。

爲了做相反的是微不足道:

response = {x,y['private'] for x,y in out.iteritems()} 

它構造一個字典用於每個foobar僅包含數據標記private。但有標準庫的一些功能(itertools也許),將產生以下:

out = { 
    'foo': { 'public':{}, 'other':{} }, 
    'bar': { 'public':{}, 'other':{} } 
} 

我曾嘗試以下:

{x:(y['public'], y['other']) for x,y in out.iteritems()} 

雖然我寧願不使用一個元組,和不明確地命名每個子結構,因爲這不是可重用的或可擴展的。

def remove(name, obj): 
    return {x:y for x,y in obj.iteritems() if x is not name} 
{x:remove('private',y) for x,y in out.iteritems()} 

這似乎工作,但有沒有更好的方法?有任何想法嗎?

回答

2

您可以將其分解爲多個部分;你需要一個刪除了一些部分的新字典。因此,創建一個函數,可以返回一個沒有問題的元素的字典,並調用它是迭代器的一部分。

您使用字典解析所以像這樣的工作:

def remove_items(d, *items): 
    """ 
    Return dictionary copy with some items removed. 
    """ 
    return { a: b for a, b in d.iteritems() if a not in items } 

print { x: remove_items(y, 'private') for x, y in out.iteritems() } 
+0

這實質上是我嘗試過的最後一件事,但是我喜歡這裏我可以指定多個鍵的事實。這是很好,乾淨。謝謝。 – Aesthete 2012-08-16 12:00:51

+0

我喜歡你的回答比我的回答更普遍,但我仍然會寫'remove_items'來複制原始文件,然後'刪除'不需要的文件。這樣你只需遍歷[大概更短的]不需要的列表,而不是完整的字典鍵列表。 – Duncan 2012-08-16 12:00:55

+0

@Duncan我原本打算建議在副本上使用del,而不是用一行代碼。在簡單的數據類型例如字典中,我懷疑這會更快。在要刪除的值是複雜類型的情況下,複製它們以便再次丟棄它們可能會更加昂貴。 – 2012-08-16 12:09:52

0

這是你的意思嗎?

respose = {x:{'public': y['public'], 'other': y['other']} for x,y in out.iteritems()}

0

試試這個:

response = {} 
for x,y in out.iteritems(): 
    response[x] = dict(y) 
    del response[x]['private'] 

如果你不介意破壞原有的字典那麼就遍歷它del '私人'元素,否則你需要複製第二級別的字典,然後複製不需要的項目。

+0

謝謝,但我試圖只在響應中暴露某些數據,而不是破壞原始數據。感謝你的回答。 – Aesthete 2012-08-16 12:00:14

+0

這就是爲什麼我發佈的代碼不會破壞原始代碼。 – Duncan 2012-08-16 12:01:29

+0

對不起,我誤解了你的代碼。我明白你現在做了什麼。 – Aesthete 2012-08-16 12:01:55