2014-10-30 4 views
0

У меня есть словарь в Python, который имеет значение словаря, как это:Как заказать словарь словарей на основе значения внутренней словаря

{'q1': {'d1': 1.2 , 'd5': 5.2}, 
'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1}, 
'q3': {'d3': 0.5}} 

Я хочу, чтобы ранжировать этот словарь и показать d переменные на основе уменьшения стоимости связанные с ними значения float .

Результаты должны быть такими:

['d5', 'd8', 'd7', 'd4', 'd1', 'd3'] 

это часть кода, который я написал, чтобы заполнить мой словарь:

if q not in result.keys(): 
    result[q] = {id:rsv[id]} 
elif id not in result[q]: 
    result[q][id]=rsv[id] 

Я хочу показать идентификаторе, которые отсортированы по значения rsv. Есть ли способ сделать это? Или есть альтернативное решение для ранжирования словаря на основе ряда значений?

+0

Теперь у вас есть несколько ключей во вложенном dict. ** Какой ключ ** должен быть отсортирован по этим словарям? Какой ключ должен быть возвращен? –

+0

Вы пытаетесь рассматривать все вложенные словари как единое целое? –

+0

Я обновил сообщение, основываясь на ваших комментариях по одному из ответов (после удаления). Такая информация должна быть частью вашего вопроса, а не скрыта в комментариях. –

ответ

0

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

Этот ответ содержит промежуточные результаты, которые часто необходимы, по моему опыту. Он сохраняет их как словари до конца, где нужны только ключи.

Во-первых, версия Python 2.x только потому, что:

d = {'q1': {'d1': 1.2 , 'd5': 5.2}, 
    'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1}, 
    'q3': {'d3': 0.5}} 

# First, flatten to a list of one key-value pair dictionaries 
inner_dicts = [ 
    dict([(k,v)]) 
    for inner_d in d.values() 
     for (k, v) in inner_d.items()] 

# Second, sort that list based on the value in each dict 
dictlist_sorted = sorted(
    inner_dicts, 
    key=lambda temp_d: temp_d.values()[0], 
    reverse=True) 

# Third, extract the key of each dict 
keys_sorted = [temp_d.keys()[0] for temp_d in dictlist_sorted] 

print keys_sorted 

Во-вторых, версия Python 3:

d = {'q1': {'d1': 1.2 , 'd5': 5.2}, 
    'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1}, 
    'q3': {'d3': 0.5}} 

# First, flatten to a list of one key-value pair dictionaries 
inner_dicts = [ 
    dict([(k,v)]) 
    for inner_d in d.values() 
     for (k, v) in inner_d.items()] 

# Second, sort that list based on the value in each dict 
dictlist_sorted = sorted(
    inner_dicts, 
    key=lambda temp_d: list(temp_d.values())[0], 
    reverse=True) 

# Third, extract the key of each dict 
keys_sorted = [list(temp_d.keys())[0] for temp_d in dictlist_sorted] 

print(keys_sorted) 
+0

Внутренние dicts будут иметь более одной пары ключ-значение. Можно ли сортировать этот тип dict? – Papar

+0

@Papar, я обновил свой ответ (хотя вы уже приняли другой ответ). –

0

Сортировки значение, извлеченное в кортежи значения и ключа (в указанном порядке), а затем извлечь ключ:

[key for value, key in sorted(
    (item[::-1] for d in outer.values() for item in d.items()), 
    reverse=True)] 

Выражение (item[::-1] for d in outer.values() for item in d.items()) извлекает (key, value) пару из каждого вложенного словаря значения, реверсивный ключ и ценность для легкой сортировки.

Сортировка затем принимает первые значения, обратные, после чего внешнее понимание списка извлекает только ключи снова.

Демо:

>>> d = {'q1': {'d1': 1.2 , 'd5':5.2}, 'q2': {'d4': 3.23, 'd7':3.9 , 'd8':4.1}, 'q3': {'d3': 0.5}} 
>>> outer = {'q1': {'d1': 1.2 , 'd5':5.2}, 'q2': {'d4': 3.23, 'd7':3.9 , 'd8':4.1}, 'q3': {'d3': 0.5}} 
>>> sorted((item[::-1] for d in outer.values() for item in d.items()), reverse=True) 
[(5.2, 'd5'), (4.1, 'd8'), (3.9, 'd7'), (3.23, 'd4'), (1.2, 'd1'), (0.5, 'd3')] 
>>> [key for value, key in sorted(
...  (item[::-1] for d in outer.values() for item in d.items()), 
...  reverse=True)] 
['d5', 'd8', 'd7', 'd4', 'd1', 'd3'] 
+0

Спасибо, но я получил эту ошибку: объект «dict_items» не поддерживает индексирование – Papar

+0

@Papar: вы используете Python 3; Я обновлю. –

+0

Да, BTW имя моего словаря - результат, и это код, который я пробовал: [ключ для значения, ключ в отсортированном ((результат [q] .items() [0] [:: - 1] для результата [ q] в result.values ​​()))] – Papar

0

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

d_sorted = sorted(d.items(), reverse=True, key=lambda x: list(x[1].values())[0]) 

Затем отобразить данные:

print(', '.join(list(x[1].keys())[0] for x in d_sorted)) 

В целом это хорошая идея, потому что вы можете повторно использовать отсортированные данные в полном объеме.

+0

OP использует Python 3, поэтому '.keys() [0]' здесь не работает. –

+0

@ martijn-pieters Правильно. Исправлена. – whereswalden

+0

За исключением того, что в вызове печати отсутствуют скобки. –

1

Поскольку оп изменил спецификации, чтобы иметь несколько пар ключ-значение в внутренний dicts, я думал, что я продемонстрирую решение, которое опирается на некоторые идеи из @ jarno-lamberg. Ключ здесь состоит в том, что, поскольку кажется, что внешнее отображение не имеет значения, я сначала захватываю все dicts и сглаживаю их в список кортежей.

d = {'q1': {'d1': 1.2 , 'd5': 5.2}, 
     'q2': {'d4': 3.23, 'd7': 3.9 , 'd8': 4.1}, 
     'q3': {'d3': 0.5}} 
d_flattened = [(k,v) for temp_d in d.values() for k,v in temp_d.items()] 
d_sorted = sorted(d_flattened, key=lambda i: i[1], reverse=True) 
print(', '.join(k for k,v in d_sorted)) 
+0

Это сработало! Большое спасибо :) – Papar

+0

@Papar: обратите внимание, что это * точно *, что мое решение выполняет. –

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