web-dev-qa-db-fra.com

Trouver les indices des éléments correspondants dans la liste dans Python

J'ai une longue liste de nombres flottants allant de 1 à 5, appelée "moyenne", et je veux renvoyer la liste des indices pour les éléments plus petits que a ou plus grands que b

def find(lst,a,b):
    result = []
    for x in lst:
        if x<a or x>b:
            i = lst.index(x)
            result.append(i)
    return result

matches = find(average,2,4)

Mais de façon surprenante, la sortie des "correspondances" contient beaucoup de répétitions, par exemple [2, 2, 10, 2, 2, 2, 19, 2, 10, 2, 2, 42, 2, 2, 10, 2, 2, 2, 10, 2, 2, ...].

Pourquoi cela arrive-t-il?

27
Logan Yang

Vous utilisez .index() qui ne trouvera que la première occurrence de votre valeur dans la liste. Donc, si vous avez une valeur 1.0 à l'index 2 et à l'index 9, alors .index(1.0) sera toujours renverra 2, Peu importe combien de fois 1.0 Apparaît dans la liste.

Utilisez plutôt enumerate() pour ajouter des index à votre boucle:

def find(lst, a, b):
    result = []
    for i, x in enumerate(lst):
        if x<a or x>b:
            result.append(i)
    return result

Vous pouvez réduire cela en une liste de compréhension:

def find(lst, a, b):
    return [i for i, x in enumerate(lst) if x<a or x>b]
55
Martijn Pieters

C'est une dépendance assez lourde, mais si vous faites beaucoup de ce genre de chose, vous devriez envisager d'utiliser numpy.

In [56]: import random, numpy

In [57]: lst = numpy.array([random.uniform(0, 5) for _ in xrange(1000)]) # example list

In [58]: a, b = 1, 3

In [59]: numpy.flatnonzero((lst > a) & (lst < b))[:10]
Out[59]: array([ 0, 12, 13, 15, 18, 19, 23, 24, 26, 29])

En réponse à la question de Seanny123, j'ai utilisé ce code de synchronisation:

import numpy, timeit, random

a, b = 1, 3

lst = numpy.array([random.uniform(0, 5) for _ in xrange(1000)])

def numpy_way():
    numpy.flatnonzero((lst > 1) & (lst < 3))[:10]

def list_comprehension():
    [e for e in lst if 1 < e < 3][:10]

print timeit.timeit(numpy_way)
print timeit.timeit(list_comprehension)

La version numpy est 60 fois plus rapide.

2
Alex Coventry