191 votes

Indexer tous les éléments *à l'exception* d'un seul en python

Existe-t-il un moyen simple d'indexer tous les éléments d'une liste (ou d'un tableau, ou autre) ? sauf pour un indice particulier ? Par exemple,

  • mylist[3] renvoie l'élément en position 3

  • milist[~3] renvoie toute la liste à l'exception de 3

8voto

Vlad Bezden Points 5024

Je vais fournir un moyen fonctionnel (immuable) de le faire.

  1. La méthode standard et la plus simple consiste à utiliser le découpage en tranches :

    index_to_remove = 3
    data = [*range(5)]
    new_data = data[:index_to_remove] + data[index_to_remove + 1:]
    
    print(f"data: {data}, new_data: {new_data}")

    Sortie :

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
  2. Utiliser la compréhension des listes :

    data = [*range(5)]
    new_data = [v for i, v in enumerate(data) if i != index_to_remove]
    
    print(f"data: {data}, new_data: {new_data}") 

    Sortie :

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
  3. Utiliser la fonction de filtrage :

    index_to_remove = 3
    data = [*range(5)]
    new_data = [*filter(lambda i: i != index_to_remove, data)]

    Sortie :

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
  4. Utilisation du masquage. Le masquage est fourni par itertools.compress de la bibliothèque standard :

    from itertools import compress
    
    index_to_remove = 3
    data = [*range(5)]
    mask = [1] * len(data)
    mask[index_to_remove] = 0
    new_data = [*compress(data, mask)]
    
    print(f"data: {data}, mask: {mask}, new_data: {new_data}")

    Sortie :

    data: [0, 1, 2, 3, 4], mask: [1, 1, 1, 0, 1], new_data: [0, 1, 2, 4]
  5. Utilisation itertools.filterfalse de la bibliothèque standard de Python

    from itertools import filterfalse
    
    index_to_remove = 3
    data = [*range(5)]
    new_data = [*filterfalse(lambda i: i == index_to_remove, data)]
    
    print(f"data: {data}, new_data: {new_data}")

    Sortie :

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]

1voto

Pour 1D numpy , np.concatenate est plus rapide que np.arange méthode.

Critères d'évaluation :

x = np.arange(1000) * 2
i = 3

%timeit np.concatenate((x[:i],x[i+1:]))
%timeit x[np.arange(len(x))!=i]

# 9.21 µs ± 467 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# 32.8 µs ± 7.46 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

1voto

cheese_codes Points 11
idxs = list(range(len(array))).remove(idx)
array[idxs]

Cela devrait fonctionner, en supprimant l'index inutile et en découpant le tableau en tranches.

0voto

aberger Points 1224

Si vous ne connaissez pas l'index à l'avance, voici une fonction qui fonctionnera

def reverse_index(l, index):
    try:
        l.pop(index)
        return l
    except IndexError:
        return False

0voto

shahar_m Points 727

Notez que si la variable est une liste de listes, certaines approches échoueront. Par exemple, si la variable est une liste de listes, certaines approches échoueront :

v1 = [[range(3)] for x in range(4)]
v2 = v1[:3]+v1[4:] # this fails
v2

Pour le cas général, utiliser

removed_index = 1
v1 = [[range(3)] for x in range(4)]
v2 = [x for i,x in enumerate(v1) if x!=removed_index]
v2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X