2015-05-17 2 views
1

У меня есть словарь Python:Python Рейтинг словарь Return Ранг

x = {'a':10.1,'b':2,'c':5}

Как идти о рейтинге и возвращения значения ранга? Как получить обратно:

res = {'a':1,c':2,'b':3}

Thanks

Edit:

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

+3

Что такое ранг значение? Как значение 'b' превращается в' 3'? –

+0

По значению рангов, вы имеете в виду положение ключа и значение в словаре, подобное индексированию массивов? – Zizouz212

+0

1 означает наивысшее значение, а 3 означает самое низкое значение – user1234440

ответ

0

Сначала сортируйте по значению в dict, затем назначьте ряды. Удостоверьтесь, что вы отменили вспять, а затем воссоздаете dict с рангом.

из предыдущего ответа:

import operator 
x={'a':10.1,'b':2,'c':5} 
sorted_x = sorted(x.items(), key=operator.itemgetter(1), reversed=True) 
out_dict = {} 
for idx, (key, _) in enumerate(sorted_x): 
    out_dict[key] = idx + 1 
print out_dict 
+0

Какой смысл вернуть его в словарь? – Makoto

+0

Разве OP не хочет вернуть его в dict? – Rcynic

+0

На самом деле нет никакого смысла. Сам словарь не сортирован, поэтому размещение сортированных данных в несортированной структуре данных для меня не имеет смысла. – Makoto

8

Если я правильно понимаю, вы можете просто использовать sorted, чтобы получить заказ, а затем enumerate пронумеровать их:

>>> x = {'a':10.1, 'b':2, 'c':5} 
>>> sorted(x, key=x.get, reverse=True) 
['a', 'c', 'b'] 
>>> {key: rank for rank, key in enumerate(sorted(x, key=x.get, reverse=True), 1)} 
{'b': 3, 'c': 2, 'a': 1} 

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

>>> x = {'a':10.1, 'b':2, 'c': 5, 'd': 5} 
>>> {key: rank for rank, key in enumerate(sorted(x, key=x.get, reverse=True), 1)} 
{'a': 1, 'b': 4, 'd': 3, 'c': 2} 

но

>>> r = {key: rank for rank, key in enumerate(sorted(set(x.values()), reverse=True), 1)} 
>>> {k: r[v] for k,v in x.items()} 
{'a': 1, 'b': 3, 'd': 2, 'c': 2} 
+1

В последнем случае 'b' должно быть' 4', на мой взгляд, потому что 'd' и' c' связаны в позиции '2'. для сохранения правильного числа букв 'b' должно быть' 4'. как это можно достичь? – beta

+0

@beta: на самом деле это не мнение о том, что правильно, просто другая вещь, которую вы хотите. :-) Но если у вас есть новый вопрос, пожалуйста, откройте новый вопрос - никто не увидит его в старом комментарии. – DSM

+0

мнение или нет, обычно это делается так. посмотрите на все спортивные рейтинги. если в одной позиции есть 2 человека, следующая назначенная позиция - +1. во всяком случае, могут быть случаи использования, когда это не так полезно. спасибо, я открою новый вопрос, если я не найду ответ в другом месте. см. также: http://stackoverflow.com/questions/23641054/adding-a-rank-to-a-dict-in-python#comment36307322_23641054 – beta

0

Вы могли бы сделать так,

>>> x = {'a':10.1,'b':2,'c':5} 
>>> m = {} 
>>> k = 0 
>>> for i in dict(sorted(x.items(), key=lambda k: k[1], reverse=True)): 
     k += 1 
     m[i] = k 


>>> m 
{'a': 1, 'c': 2, 'b': 3} 
+0

Это работает, но во многих местах излишне усложняется (см. ответ DSM): (1) С вашей переменной 'k' вы вручную перерабатываете то, что Python предоставляет с помощью' enumerate'. (2) Нет необходимости в явном преобразовании 'int': Python знает, как напрямую сравнивать объекты. (3) Ваше 'update' всегда записывается как' m [i] = k'. – EOL

0

Довольно простой рода-простой, но вид комплекса один-лайнер.

{key[0]:1 + value for value, key in enumerate(
         sorted(d.iteritems(), 
           key=lambda x: x[1], 
           reverse=True))} 

Позвольте мне провести вас через это.

  • Мы используем enumerate, чтобы дать нам естественный порядок элементов, основанных на нуле. Просто используя enumerate(d.iteritems()), вы создадите список кортежей, которые содержат целое число, а затем набор, содержащий пару ключ: значение из исходного словаря.
  • Мы сортируем список, чтобы он отображался в порядке от наивысшего до самого низкого.
  • Мы хотим обработать значение как перечислимое значение (то есть, мы хотим, чтобы 0 было значением для 'a', если есть только одно вхождение (и я немного доработаю это), и так далее), и мы хотим, чтобы ключ был фактическим ключом из словаря. Итак, мы заменим порядок, в котором мы связываем два значения.
  • Когда приходит время извлечь фактический ключ, он все еще находится в форме кортежа - он отображается как ('a', 0), поэтому мы хотим получить только первый элемент. key[0] выполняет это.
  • Когда мы хотим получить фактическое значение, мы нормализуем его ранжирование так, чтобы оно основано на 1, а не на основе нуля, поэтому мы добавляем 1 к value.
+0

«Боб пришел первым, вторым или третьим?» это разумный вопрос, и d [«Bob»] == 3 дает ответ. То, что словари не упорядочены, не означает, что карта между ключом и рангом не может быть полезна. – DSM

+0

Это справедливо. Я немного передумаю. – Makoto

0
In [23]: from collections import OrderedDict 

In [24]: mydict=dict([(j,i) for i, j in enumerate(x.keys(),1)]) 

In [28]: sorted_dict = sorted(mydict.items(), key=itemgetter(1)) 

In [29]: sorted_dict 
Out[29]: [('a', 1), ('c', 2), ('b', 3)] 
In [35]: OrderedDict(sorted_dict) 
Out[35]: OrderedDict([('a', 1), ('c', 2), ('b', 3)]) 
+0

Разве это не совсем точная копия моего ответа? – Zizouz212

+0

@ Zizouz212 Вы не использовали перечисление, вы приводили пример, используя цифры – Ajay

+0

Ваша 28-я строка - это ** точная ** копия моего ответа, я нахожу что-то странное в этом. Переменные имена, методы, все то же самое. – Zizouz212

0

Одним из способов было бы изучить словарь для наибольшего значения, а затем удалить его, в то время как строительство нового словаря:

my_dict = x = {'a':10.1,'b':2,'c':5} 
i = 1 
new_dict ={} 
while len(my_dict) > 0: 
    my_biggest_key = max(my_dict, key=my_dict.get) 
    new_dict[my_biggest_key] = i 
    my_dict.pop(my_biggest_key) 
    i += 1 
print new_dict 
+0

Это решение кажется не-питоновым и громоздким. Есть более элегантные способы достижения того, к чему вы пытаетесь, без необходимости прибегать к заявлению while. – Makoto

+1

Итак, что. Не причина для голосования. Если это сработает, тогда это полезно. – Zizouz212

+0

(Я не оригинал downvoter) Решение, которое работает, полезно в том, что оно может решить проблему. Тем не менее, он может даже быть _counterproductive_, показывая какой-то метод или стиль, который должен быть _объяснен любым программистом, если они не хотят тратить 80% своего времени: ответ DSM берет две строки, поэтому быстрее пишите, это также более разборчиво. Я утверждал бы, что это _counterproductive_ делать вещи, как в этом ответе, поэтому я хочу, чтобы препятствовать людям использовать его, или у них будет много, еще много вопросов в будущем, с кодом, который долго читать и труднее понять. – EOL

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