Je veux trouver uniquement les 3 premiers éléments distincts par ordre décroissant. S'il y a un départage, triez par ordre alphabétique. S'il y a 3 éléments ou moins, le renvoi de la liste distincte des éléments est suffisant.

Donc si j'ai la saisie de : ["a","a","b","b","c","c","c","d","d","d","d"]

La sortie sera ["d","c","a"]

Parce que d a 4 comptes, c 3 comptes, a et b ont la même fréquence, mais a est le premier par ordre alphabétique.

Dans MySQL, j'utiliserais généralement ceci:

SELECT id, COUNT(*) as frequency FROM mylist GROUP BY id ORDER BY frequency, id

Comment puis-je faire cela en Python?

J'utilise ce code basé sur la solution de SAI SANTOH CHIRAG :

def main(output):
    arr = sorted(output,key=lambda i:[output.count(i),-ord(i)],reverse=True)
    out = []
    for i in arr: 
        if i not in out: out.append(i) 
        print(out[:3])

Mais pourquoi le résultat est comme ça :

Input (stdin) = a a a b b c d d d d
output = ['d']
['d']
['d']
['d']
['d', 'a']
['d', 'a']
['d', 'a']
['d', 'a', 'b']
['d', 'a', 'b']
['d', 'a', 'b']

Au lieu de ce que je veux, ce serait :

['d','a','b']
5
18818181881 17 mars 2021 à 09:13

4 réponses

Meilleure réponse

Vous utilisez trié et clé pour cela. Essayez de cette façon :

arr = sorted(x,key=lambda i:[x.count(i),-ord(i)],reverse=True)

Avec cela, vous obtenez tous les éléments dans l'ordre trié dans l'augmentation du nombre, puis dans l'ordre alphabétique. Ensuite, faites ceci pour obtenir tous les éléments une seule fois :

out = []
for i in arr:
    if i not in out:
        out.append(i)
print(out[:3])
4
SAI SANTOSH CHIRAG 17 mars 2021 à 06:38

Vous pouvez utiliser Counter à partir de collections

from collections import Counter

inputs = ["a","a","b","b","c","c","c","d","d","d","d"]
counts = Counter(x)
counts.most_common(3)

final = [i[0] for i in counts.most_common]

Sortie pour counts.most_common()

[('d', 4), ('c', 3), ('a', 2), ('b', 2)]
1
sammy 17 mars 2021 à 06:24

Plus simple et plus efficace que la réponse acceptée.

>>> a = ["a","a","b","b","c","c","c","d","d","d","d"]

>>> sorted(set(a), key=lambda s: (-a.count(s), s))[:3]
['d', 'c', 'a']

Cela supprime les doublons d'abord et ne compte donc chaque chaîne qu'une seule fois. En outre, il est préférable d'annuler simplement le nombre au lieu du code de caractère et d'utiliser le tri inversé. Si les chaînes comportaient plusieurs caractères, vous ne pouviez même pas du tout utiliser le code de caractère.

Un autre, en utilisant deux tris plus simples (peut-être en fait plus rapide) :

>>> sorted(sorted(set(a)), key=a.count, reverse=True)[:3]
['d', 'c', 'a']
0
Manuel 24 mars 2021 à 22:43

collections.Counter fera :

the_list = ["a","a","b","b","c","c","c","d","d","d","d"]
counter = Counter(sorted(the_list))
top_3 = counter.most_common(3)

À ce stade, top_3 est de la forme [(<entry>, <freq>)], par ex.

[('d', 4), ('c', 3), ('a', 2)]

En retirer les premiers éléments via la compréhension de liste :

result = [item for item, freq in top_3]

Et nous obtenons

['d', 'c', 'a']

Remarques:

  1. Nous passons la liste sorted au Counter car sinon cela rompra les liens selon l'ordre d'insertion ; le tri force l'ordre d'insertion à être en quelque sorte l'ordre alphabétique.

  2. .most_common(3) renverra au plus 3 éléments donc tout va bien, par ex. même s'il n'y a que 2 entrées uniques. Par exemple. si the_list = ["b", "a"], result sera ["a", "b"] même si le nombre d'éléments uniques est inférieur à 3.

2
Mustafa Aydın 17 mars 2021 à 06:23