Hé, c'est ma première question alors j'espère que je le fais bien

J'essaie d'écrire une fonction qui a donné une liste d'entiers et N comme occurrence maximale, renverrait alors une liste avec tout entier supérieur à l'occurrence maximale supprimée. Par exemple si je saisis: [20,37,20,21] #list of integers et 1 #maximum occurrence. Ensuite, en sortie, j'obtiendrais: [20,37,21] car le nombre 20 apparaît deux fois et l'occurrence maximale est 1, il est donc supprimé de la liste. Voici un autre exemple: Input: [1,1,3,3,7,2,2,2,2], 3 Output: [1,1,3,3,7,2,2,2]

Voici ce que j'ai écrit jusqu'à présent, comment pourrais-je l'optimiser? J'obtiens toujours une erreur de temporisation. Merci beaucoup d'avance.

def delete_nth(order,n):
    order = Counter(order)
    for i in order:
        if order[i] > n:
            while order[i] > n:
                order[i] - 1
    return order

print(delete_nth([20,37,20,21], 1))
-1
Kryptos 7 oct. 2020 à 13:26

4 réponses

Meilleure réponse

Vous pouvez supprimer la construction du Counter au début - et avoir juste un dictionnaire temporaire comme compteur:

def delete_nth(order,n):
    out, counter = [], {}
    for v in order:
        counter.setdefault(v, 0)
        if counter[v] < n:
            out.append(v)
            counter[v] += 1
    return out

print(delete_nth([20,37,20,21], 1))

Tirages:

[20, 37, 21]
1
Andrej Kesely 7 oct. 2020 à 10:36

Tu as écrit:

    while order[i] > n:
        order[i] - 1

Cette deuxième ligne devrait vraisemblablement être order[i] -= 1, ou tout code entrant dans la boucle ne la quittera jamais.

0
ShadowRanger 7 oct. 2020 à 10:28

J'ai renommé les variables en quelque chose qui avait plus de sens pour moi:

Cette version, bien que très courte et assez efficace, produira des valeurs identiques de manière adjacente:

from collections import Counter

def delete_nth(order, n):
    counters = Counter(order)
    output = []
    for value in counters:
        cnt = min(counters[value], n)
        output.extend([value] * cnt)
    return output

print(delete_nth([1,1,2,3,3,2,7,2,2,2,2], 3))
print(delete_nth([20,37,20,21], 1))

Tirages:

[1, 1, 2, 2, 2, 3, 3, 7]
[20, 37, 21]

Cette version maintiendra l'ordre d'origine, mais fonctionnera un peu plus lentement:

from collections import Counter

def delete_nth(order, n):
    counters = Counter(order)
    for value in counters:
        counters[value] = min(counters[value], n)
    output = []
    for value in order:
        if counters[value]:
            output.append(value)
            counters[value] -= 1
    return output

print(delete_nth([1,1,2,3,3,2,7,2,2,2,2], 3))
print(delete_nth([20,37,20,21], 1))

Tirages:

[1, 1, 2, 3, 3, 2, 7, 2]
[20, 37, 21]
0
Booboo 7 oct. 2020 à 11:20

Vous pouvez utiliser un prédicat avec un argument par défaut collections.defaultdict pour conserver l'état lorsque votre liste de nombres est filtrée.

def delete_nth(numbers, n):
    from collections import defaultdict
    def predicate(number, seen=defaultdict(int)):
        seen[number] += 1
        return seen[number] <= n
    return list(filter(predicate, numbers))

print(delete_nth([1, 1, 3, 3, 7, 2, 2, 2, 2], 3))
        

Production:

[1, 1, 3, 3, 7, 2, 2, 2]
>>> 
0
Paul M. 7 oct. 2020 à 11:52