2017-02-20 140 views
1

嗨,我試圖解決字典和基於成功 打印值如果「成功」的值爲真不是增加1否則爲0 爲前:字典是蟒蛇情結字典理解

info = {'data': {'sample1': {'item': 'fruit1', 
          'id': 1, 
          'results': {'Apple': [{ 
           'start_ts': 1487579550, 
           'success': True}], 
           'Mango': [{ 
            'start_ts': 1487579550, 
            'success': True}] 
          } 
          }, 
       'sample2': {'item': 'fruit1', 
          'id': 2, 
          'results': {'Apple': [{ 
           'start_ts': 1487579550, 
           'success': True}], 
           'Mango': [{ 
            'start_ts': 1487579550, 
            'success': False}] 
          } 
          }, 
       'sample3': {'item': 'fruit2', 
          'id': 3, 
          'results': {'Apple': [{ 
           'start_ts': 1487579550, 
           'success': True}], 
           'Mango': [{ 
            'start_ts': 1487579550, 
            'success': False}] 
          } 
          } 
       }} 

產出應該基於「水果1」和水果2的所有項目的成功,並且需要增加。

輸出:

 Apple Mango  
fruit1 2   1 
fruit2 1   0 

什麼是迭代這個複雜的字典最佳途徑。 我嘗試了一些基本代碼:

for k, v in info.items(): 
    for i,sample in v.items(): 
     pprint.pprint(sample['results']) # Prints diction of Apples and Mango 
+3

有你嘗試自己做任何事? – depperm

+0

使用簡單的循環和數量變量必須足夠。我希望你想要的是學習如何最有效地做到這一點,所以也許你必須告訴我們你以前試圖問。 –

+0

我認爲你在代碼示例中有一個錯誤,因爲如果你有一個名爲'data'的鍵並且是一個樣本列表,你需要使用'[]'來存儲樣本列表,比如鍵值' data'。爲了使這更容易,您可以刪除樣本的名稱,如'sample1',如果您是生成字典。 –

回答

0

嗯,就像很簡單的第一種方法,你可以做這樣的事情:

fruit1 = {'Apple': 0, 'Mango': 0} 
fruit2 = {'Apple': 0, 'Mango': 0} 

for k, v in info['data'].items(): 
    if v['item'] == 'fruit1': 
     if v['results']['Apple'][0]['success']: 
      fruit1['Apple'] += 1 
     if v['results']['Mango'][0]['success']: 
      fruit1['Mango'] += 1 

    if v['item'] == 'fruit2': 
     if v['results']['Apple'][0]['success']: 
      fruit2['Apple'] += 1 
     if v['results']['Mango'][0]['success']: 
      fruit2['Mango'] += 1 


print 'fruit1: {}'.format(fruit1) 
print 'fruit2: {}'.format(fruit2) 

輸出:

fruit1: {'Mango': 1, 'Apple': 2} 
fruit2: {'Mango': 0, 'Apple': 1} 

只有永遠的名的水果是相同的(fruit1和2),這些都是蘋果和芒果。但最好的是,這不重要,你可以從這裏工作,實現你的領域的目標。這有點髒,當然不是最佳解決方案。

0

有很多方法可以得到你想要的信息,像這樣的例子

result={} 
for sample in info["data"].values(): 
    name = sample["item"] 
    inner = result.setdefault(name,{}) 
    for fruit, value in sample["results"].items(): 
     if value[0]["success"]: 
      inner[fruit] = inner.get(fruit,0) + 1 
print(result) 

說明:首先,我們決定如何得到的結果,在這種情況下,我選擇了其中的關鍵將是一個字典「 fruit1「,」fruit2「等,它們的值將是另一個字典,裏面有」蘋果「,」芒果「等。 然後我們通過迭代關鍵字「data」的值開始,因爲這是具有我們想要的信息的那個值,然後我們首先爲相應名稱的值設置初始空內部字典,並將其置於inner變量,然後我們按照迭代相應結果的項目(又名水果)和計數的成功的次數,使用get所以第一次我們爲它的計得0

輸出

{'fruit1': {'Apple': 2, 'Mango': 1}, 'fruit2': {'Apple': 1}} 

一旦你達到目的,你到達這裏,你可以用任何你想要的方式打印它


此相同的用發電機表達式的變化和collections模塊

from pprint import pprint 
from collections import Counter, defaultdict 

compact = ((s["item"],(k for k,v in s["results"].items() if v[0]["success"])) for s in info["data"].values()) 
result = defaultdict(Counter) 
for k,v in compact: 
    result[k].update(v) 
pprint(result)  

輸出

defaultdict(<class 'collections.Counter'>, 
      {'fruit1': Counter({'Apple': 2, 'Mango': 1}), 
      'fruit2': Counter({'Apple': 1})})  
0

短溶液使用熊貓,因爲嵌套詞典是用於表的好項:

pan=pd.Panel.from_dict(info['data']) 
def repl(s): return s['item'] if ~isnan(s.id) and s.results[0]['success'] else None 
df=pan.apply(repl,'minor') 
sta=df.stack().reset_index() 
cnt=sta.groupby(['level_0',0]).count().unstack().fillna(0).astype(int)  

最終結果T(cnt):

  fruit1 fruit2    
Apple   2  1 
Mango   1  0 

在詳細信息:

pan=pd.Panel.from_dict(info['data']) 

一切都是那麼自動3D組織:

<class 'pandas.core.panel.Panel'> 
Dimensions: 3 (items) x 2 (major_axis) x 3 (minor_axis) 
Items axis: sample1 to sample3 
Major_axis axis: Apple to Mango 
Minor_axis axis: id to results 

現在定義一個函數來選擇好的水果和減少2D :

def repl(s): return s['item'] if ~isnan(s.id) and s.results[0]['success'] else None 
df=pan.apply(repl,'minor') 

爲:

 sample1 sample2 sample3 
Apple fruit1 fruit1 fruit2 
Mango fruit1 None None 

最後重新組織1D:

sta=df.stack().reset_index() 

None值下降:

level_0 level_1  0 
0 Apple sample1 fruit1 
1 Apple sample2 fruit1 
2 Apple sample3 fruit2 
3 Mango sample1 fruit1 

和計數:

cnt=sta.groupby(['level_0',0]).count().unstack().fillna(0).astype(int)