Le code Python suivant semble être très long lorsqu'il vient d'un arrière-plan Matlab
>>> a = [1, 2, 3, 1, 2, 3]
>>> [index for index,value in enumerate(a) if value > 2]
[2, 5]
Quand dans Matlab je peux écrire:
>> a = [1, 2, 3, 1, 2, 3];
>> find(a>2)
ans =
3 6
Existe-t-il une méthode courte pour écrire ceci en Python, ou est-ce que je m'en tiens simplement à la version longue?
Merci pour toutes les suggestions et explications sur la justification de la syntaxe de Python.
Après avoir trouvé ce qui suit sur le site numpy, je pense avoir trouvé une solution que j'aime:
http://docs.scipy.org/doc/numpy/user/basics.indexing.html#boolean-or-mask-index-arrays
L'application des informations de ce site Web à mon problème ci-dessus donnerait ce qui suit:
>>> from numpy import array
>>> a = array([1, 2, 3, 1, 2, 3])
>>> b = a>2
array([False, False, True, False, False, True], dtype=bool)
>>> r = array(range(len(b)))
>>> r(b)
[2, 5]
Ce qui suit devrait alors fonctionner (mais je n'ai pas d'interpréteur Python sous la main pour le tester):
class my_array(numpy.array):
def find(self, b):
r = array(range(len(b)))
return r(b)
>>> a = my_array([1, 2, 3, 1, 2, 3])
>>> a.find(a>2)
[2, 5]
[idx for idx in range(len(a)) if a[idx] > 2]
? La raison pour laquelle cela est un peu difficile à faire en Python est qu'il n'utilise pas autant les index que les autres langages.Réponses:
En Python, vous n'utiliseriez pas du tout d'index pour cela, mais vous traitiez simplement des valeurs—
[value for value in a if value > 2]
. Habituellement, traiter des index signifie que vous ne faites pas quelque chose de la meilleure façon.Si vous avez besoin d' une API similaire à Matlab de, vous pouvez utiliser numpy , un paquet pour les tableaux multidimensionnels et mathématiques numériques en Python qui est fortement inspiré par Matlab. Vous utiliseriez un tableau numpy au lieu d'une liste.
la source
filtered_ranges_and_angles = [(range, angle) for range, angle in zip(ranges, angles) if should_be_kept(range)]
Autrement:
En général, rappelez-vous que si
find
c'est une fonction prête à l'emploi, la compréhension de liste est une solution générale et donc très puissante . Rien ne vous empêche d'écrire unefind
fonction en Python et de l'utiliser plus tard comme vous le souhaitez. C'est à dire:Notez que j'utilise des listes ici pour imiter Matlab. Il serait plus pythonique d'utiliser des générateurs et des itérateurs.
la source
[i for i,v in enumerate(a) if v > 2]
place.index
pari
etvalue
parv
dans l'original et comptez les caractères.enumerate
overrange(len(...))
est à la fois plus robuste et plus efficace.find_indices
fonction à utiliserenumerate
Pour moi, cela fonctionne bien:
la source
Peut-être qu'une autre question est: "qu'allez-vous faire de ces indices une fois que vous les aurez?" Si vous prévoyez de les utiliser pour créer une autre liste, alors en Python, ils constituent une étape intermédiaire inutile. Si vous voulez que toutes les valeurs correspondent à une condition donnée, utilisez simplement le filtre intégré:
Ou rédigez votre propre liste de compréhension:
Si vous souhaitez les supprimer de la liste, la méthode pythonique n'est pas nécessairement de les supprimer de la liste, mais d'écrire une compréhension de liste comme si vous créiez une nouvelle liste et la réassigniez en place en utilisant le
listvar[:]
sur la gauche. -côté:Matlab fournit
find
car son modèle centré sur les tableaux fonctionne en sélectionnant des éléments à l'aide de leurs indices de tableau. Vous pouvez le faire en Python, certes, mais la manière la plus pythonique consiste à utiliser des itérateurs et des générateurs, comme déjà mentionné par @EliBendersky.la source
a[:] = ...
- voir la réponse d'Alex Martelli à cette question stackoverflow.com/questions/1352885/… .Même si c'est une réponse tardive: je pense que c'est toujours une très bonne question et IMHO Python (sans bibliothèques supplémentaires ou boîtes à outils comme numpy) manque toujours d'une méthode pratique pour accéder aux index des éléments de la liste selon un filtre défini manuellement.
Vous pouvez définir manuellement une fonction, qui fournit cette fonctionnalité:
Rendements: [0, 4]
Dans mon imagination, le moyen idéal serait de créer une classe enfant de liste et d'ajouter la fonction index comme méthode de classe. De cette façon, seule la méthode de filtrage serait nécessaire:
J'ai élaboré un peu plus sur ce sujet ici: http://tinyurl.com/jajrr87
la source