Der folgende Python-Code scheint sehr langwierig zu sein, wenn er aus einem Matlab-Hintergrund stammt
>>> a = [1, 2, 3, 1, 2, 3]
>>> [index for index,value in enumerate(a) if value > 2]
[2, 5]
Wenn ich in Matlab bin, kann ich schreiben:
>> a = [1, 2, 3, 1, 2, 3];
>> find(a>2)
ans =
3 6
Gibt es eine Kurzhandmethode, um dies in Python zu schreiben, oder bleibe ich einfach bei der Langversion?
Vielen Dank für alle Vorschläge und Erklärungen zur Begründung der Python-Syntax.
Nachdem ich auf der numpy-Website Folgendes gefunden habe, habe ich eine Lösung gefunden, die mir gefällt:
http://docs.scipy.org/doc/numpy/user/basics.indexing.html#boolean-or-mask-index-arrays
Das Anwenden der Informationen von dieser Website auf mein obiges Problem würde Folgendes ergeben:
>>> 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]
Folgendes sollte dann funktionieren (aber ich habe keinen Python-Interpreter zur Hand, um es zu testen):
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]
? Der Grund, warum dies in Python etwas umständlich ist, liegt darin, dass Indizes nicht so häufig verwendet werden wie in anderen Sprachen.Antworten:
In Python würden Sie dafür überhaupt keine Indizes verwenden, sondern sich nur mit den Werten befassen -
[value for value in a if value > 2]
. Normalerweise bedeutet der Umgang mit Indizes, dass Sie etwas nicht am besten tun.Wenn Sie noch eine API müssen ähnlich wie Matlab, würden Sie verwenden numpy , ein Paket für mehrdimensionale Arrays und numerische Mathematik in Python , die stark von Matlab inspiriert. Sie würden ein Numpy-Array anstelle einer Liste verwenden.
quelle
filtered_ranges_and_angles = [(range, angle) for range, angle in zip(ranges, angles) if should_be_kept(range)]
Ein anderer Weg:
Im Allgemeinen denken Sie daran , dass , während
find
eine fertig zubereitete Funktion sind Listenkomprehensionen ein General, und damit sehr leistungsfähige Lösung . Nichts hindert Sie daran, einefind
Funktion in Python zu schreiben und sie später nach Ihren Wünschen zu verwenden. Dh:Beachten Sie, dass ich hier Listen verwende, um Matlab nachzuahmen. Es wäre pythonischer, Generatoren und Iteratoren zu verwenden.
quelle
[i for i,v in enumerate(a) if v > 2]
stattdessen so schreiben können .index
durchi
undvalue
mitv
und zählen Sie die Zeichen.enumerate
overrange(len(...))
ist sowohl robuster als auch effizienter.find_indices
zu verwendende Funktion ändernenumerate
Bei mir funktioniert es gut:
quelle
Vielleicht ist eine andere Frage: "Was machen Sie mit diesen Indizes, wenn Sie sie erhalten?" Wenn Sie sie zum Erstellen einer weiteren Liste verwenden möchten, sind sie in Python ein unnötiger mittlerer Schritt. Wenn Sie alle Werte möchten, die einer bestimmten Bedingung entsprechen, verwenden Sie einfach den integrierten Filter:
Oder schreiben Sie Ihre eigene Liste:
Wenn Sie sie aus der Liste entfernen möchten, besteht die pythonische Methode nicht darin, sie unbedingt aus der Liste zu entfernen, sondern ein Listenverständnis zu schreiben, als würden Sie eine neue Liste erstellen und sie mithilfe
listvar[:]
der linken Seite wieder an Ort und Stelle zuweisen -Seite:Matlab liefert,
find
weil sein Array-zentriertes Modell Elemente anhand ihrer Array-Indizes auswählt. Sie können dies sicherlich in Python tun, aber der pythonischere Weg ist die Verwendung von Iteratoren und Generatoren, wie bereits von @EliBendersky erwähnt.quelle
a[:] = ...
- siehe Alex Martellis Antwort auf diese Frage stackoverflow.com/questions/1352885/… .Auch wenn es eine späte Antwort ist: Ich denke, dies ist immer noch eine sehr gute Frage, und IMHO Python (ohne zusätzliche Bibliotheken oder Toolkits wie numpy) fehlt immer noch eine bequeme Methode, um auf die Indizes von Listenelementen gemäß einem manuell definierten Filter zuzugreifen.
Sie können manuell eine Funktion definieren, die diese Funktionalität bietet:
Ausbeuten: [0, 4]
In meiner Vorstellung wäre der perfekte Weg, eine untergeordnete Listenklasse zu erstellen und die Indizes als Klassenmethode hinzuzufügen. Auf diese Weise würde nur die Filtermethode benötigt:
Ich habe hier etwas mehr zu diesem Thema ausgeführt: http://tinyurl.com/jajrr87
quelle