2015-04-08 3 views
0

Как я пишу это вещий образом: counts_to_display является defaultdict (DICT), который имеет следующие данные:Как написать defaultdict более питоническим способом?

defaultdict(<type 'dict'>, 
      {'server01': {'metric1': 9}, 
      'server02': {'metric1': 12}, 
      'server03': {'metric3': 8}, 
      'server04': {'metric1': 11, 'metric2': 7} 
      }) 



headers = [] 
for count in counts_to_display: 
     for name in counts_to_display[count]: 
       if name not in headers: 
         headers.append(name) 

мне нужно напечатать все в таблице:

Server Metric1 Metric2 Metric3 
server01 9  0  0 
server02 12  0  0 
server03 0  0  8 
server04 11  7  0 
+0

Если заказ не имеет значения изменения 'headers' в' set'. Это лучшее, что вы можете сделать, я думаю. – thefourtheye

+0

Какой выход вы ожидаете? Ваш код не уточняет это. – wenzul

+0

@wenzul добавил мое ожидание в вопрос –

ответ

0

Вот одно решение :

headers = {key for count in counts_to_display.values() for key in count} 

Я использую набор вместо списка, так как мы работаем со словарем как входным, который имеет арбитраж в любом случае, поэтому было бы бессмысленно хотеть сохранить порядок в обращении, а также автоматически заботится о дедупликации для нас, а также более эффективны для определенных операций.

Вы можете использовать следующее тоже:

import itertools 
headers = set(itertools.chain.from_iterable(counts_to_display.values())) 
+0

спасибо, пример itertools выглядит красиво –

+0

'itertools' является своего рода излишним для этого простого вызова ...;) – wenzul

+0

Я сам предпочел бы также и установившееся понимание, но я уверен, что' itertools.chain.from_iterable' более читабельна и легче обернуть голову. Не существует значительных затрат ни на импорт, ни на использование 'itertools.chain()', поэтому я бы сказал, что для этой цели это вполне разумная часть кода. – Underyx

0

Вы можете использовать list comprehension вместе с reduce, чтобы получить Вас работу

headers = set(reduce(lambda x,y : x+y, [count_to_display[count].keys() for count in count_to_display])) 
0

насчет reduce? Должно быть одним из самых быстрых решений.

print sorted(reduce(lambda x, y: x.update(y) or x, servers.itervalues()).keys()) 
0

Или так:

>>> d = {'server01': {'metric1': 9}, 
     'server02': {'metric1': 12}, 
     'server03': {'metric3': 8}, 
     'server04': {'metric1': 11, 'metric2': 7} 
     } 
>>> dicts = [x for x in d.values()] 
>>> result = reduce(lambda d, src: d.update(src) or d, dicts, {}) 
>>> result 
{'metric3': 8, 'metric2': 7, 'metric1': 11} 
>>> res = [r for r in result.keys()] 
>>> res 
['metric3', 'metric2', 'metric1'] 
+0

Использование 'dict' здесь избыточно, потому что' dict' уже имеет уникальные ключи. – wenzul

+0

Да, спасибо! сделанный! – thinkerou

Смежные вопросы