2015-04-07 7 views
0

On m'a demandé de définir une fonction pour retourner le haut utilisé 3 mots dans une phrase. Je suis en mesure de compiler une phrase souhaitée dans un dictionnaire pour que quelque chose commeTop 3 fréquence des mots dans une phrase

'test test bye bye hello hello world world world' 

est sous la forme

{'world': 3, 'hello': 2, 'bye': 2, 'test': 2} 

Cependant, je ne veux que les 3 premiers mots utilisés et comme on peut le voir , il y a un conflit entre 3 éléments du dictionnaire. En cas de conflit, il est préférable de trier les mots en conflit par ordre alphabétique de sorte que seules 3 valeurs soient renvoyées. Dans ce cas, je voudrais:

['world','bye','hello'] 

être retourné après le tri. Comment pourrais-je y aller en faisant cela?

Répondre

4

Vous pouvez utiliser la fonction key de sorted, ainsi que la façon dont tuples sont intrinsèquement classés, pour ce faire:

>>> d = {'world': 3, 'hello': 2, 'bye': 2, 'test': 2} 
>>> [x for x, y in sorted(d.items(), key=lambda (x, y): (-y, x))[:3]] 
['world', 'bye', 'hello'] 
+0

Je pense que '[x pour x, y en ordonnée (d.items(), key = lambda (x, y) : (-y, x)) [: 3]] 'serait s légèrement plus propre; vous ne gagnez aucun bénéfice de 'itertiems' ici, car tous les éléments sont nécessaires pour le tri, et avoir' x' se référer à deux choses différentes dans la même ligne est assez gênant. – jonrsharpe

+0

Vous avez probablement raison. C'est juste une habitude pour moi d'utiliser 'iteritems'! – Ben

1

Comme une façon plus pythonique pour ce problème, vous pouvez utiliser Counter fonction à partir collections Module pour obtenir le dictionnaire approprié puis utilisez sorted et un découpage simple, l'extrait les paires de désir:

>>> s='test test bye bye hello hello world world world' 
>>> from collections import Counter 
>>> sorted(Counter(s.split()).items(),key=lambda (i,j):(-j,i))[:3] 
[('world', 3), ('bye', 2), ('hello', 2)] 
+0

* "Les éléments avec des nombres égaux sont ordonnés arbitrairement" * (voir [les docs] (https://docs.python.org/2/library/collections.html#collections.Counter.most_common)), donc cela fonctionne ** pas ** répondre aux exigences du PO – jonrsharpe

+0

@ jonrsharpe désolé je peux comprendre quelle différence cela fait-il? – Kasramvd

+0

Juste ** regardez les exemples ** - l'OP veut "world", "bye" et "bonjour" (comme ils le disent, * "les mots en conflit sont mieux classés par ordre alphabétique" *), alors que votre version donne «world», «test» et «bye» – jonrsharpe