J'écris une fonction python qui consomme une liste de chaînes et produit une liste des éléments les plus fréquents.

Par exemple:

>>> trending(["banana", "trouble", "StarWars", "StarWars", "banana", "chicken", "BANANA"])
["banana", "StarWars"]

Mais

>>> trending(["banana", "trouble", "StarWars", "Starwars", "banana", "chicken"])
["banana"]

Jusqu'à présent, j'ai écrit une fonction qui produit uniquement le premier mot qui apparaît fréquemment au lieu d'une liste de mots qui apparaissent fréquemment. De plus, ma liste contient l'index de cet élément fréquent.

def trending(slst):
    words = {}
    for word in slst:
        if word not in words:
            words[word] = 0
        words[word] += 1
    return words

Comment puis-je corriger cette fonction pour produire une liste des éléments les plus fréquents (au lieu du premier des éléments les plus fréquents) et comment supprimer l'index?

2
Shagun Chhikara 12 juil. 2015 à 18:10

3 réponses

Meilleure réponse

Sans l'utilisation de Counter, vous pouvez créer votre propre compteur avec un dict et extraire des éléments fréquents:

def trending(slst):
    count = {}
    items = []

    for item in set(slst):
        count[item] = slst.count(item)

    for k, v in count.items():
        if v == max(count.values()):
            items.append(k)

    return items
3
Malik Brahimi 12 juil. 2015 à 15:40

Utilisez un Counter:

In [1]: from collections import Counter

In [2]: l = ["banana", "trouble", "StarWars", "StarWars", "banana", "chicken", "BANANA"]

In [3]: Counter(l)
Out[3]: Counter({'StarWars': 2, 'banana': 2, 'BANANA': 1, 'trouble': 1, 'chicken': 1})

Avec Counter(l).most_common(n), vous pouvez obtenir le { {X1}} éléments les plus courants.


Mise à jour

Votre fonction trending() est essentiellement ce que fait Counter également. Après avoir compté le nombre d'occurrences, vous pouvez obtenir le nombre maximal d'occurrences à l'aide de max(words.values()). Cela peut être utilisé pour filtrer votre liste de mots:

def trending(slst):
    ...
    max_occ = max(words.values())
    return [word for word, occ in words.items() if occ == max_occ]
2
Finwood 12 juil. 2015 à 15:27

La solution suivante utilise uniquement des listes. Aucun dictionary, set ou autre collection Python n'est utilisé:

def trending(words):
    lcounts = [(words.count(word), word) for word in words]
    lcounts.sort(reverse=True)
    ltrending = []

    for count, word in lcounts:
        if count == lcounts[0][0]:
            if word not in ltrending:
                ltrending.append(word)
        else:
            break

    return ltrending


ltests = [
    ["banana", "trouble", "StarWars", "StarWars", "banana", "chicken", "BANANA"],
    ["banana", "trouble", "StarWars", "Starwars", "banana", "chicken"]]

for test in ltests:
    print trending(test)

Il donne la sortie suivante:

['banana', 'StarWars']
['banana']
0
Martin Evans 13 juil. 2015 à 08:11