webentwicklung-frage-antwort-db.com.de

Verwenden Sie die list index () - Methode von Python für eine Liste von Tupeln oder Objekten?

Der Listentyp von Python verfügt über eine index () - Methode, die einen Parameter übernimmt und den Index des ersten Elements in der Liste zurückgibt, das mit dem Parameter übereinstimmt. Zum Beispiel:

>>> some_list = ["Apple", "pear", "banana", "grape"]
>>> some_list.index("pear")
1
>>> some_list.index("grape")
3

Gibt es eine elegante (idiomatische) Möglichkeit, dies auf Listen komplexer Objekte wie Tupel zu erweitern? Im Idealfall möchte ich so etwas tun können:

>>> Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11)]
>>> some_list.getIndexOfTuple(1, 7)
1
>>> some_list.getIndexOfTuple(0, "kumquat")
2

getIndexOfTuple () ist nur eine hypothetische Methode, die einen Subindex und einen Wert akzeptiert und dann den Index des Listenelements mit dem angegebenen Wert an diesem Subindex zurückgibt. Ich hoffe

Gibt es eine Möglichkeit, dieses allgemeine Ergebnis zu erzielen, indem Sie Listenverständnisse oder Lambas oder etwas "Inline" wie dieses verwenden? Ich denke, ich könnte meine eigene Klasse und Methode schreiben, aber ich möchte das Rad nicht neu erfinden, wenn Python bereits eine Möglichkeit hat, dies zu tun.

45
Ryan B. Lynch

Wie wäre es damit?

>>> Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11)]
>>> [x for x, y in enumerate(Tuple_list) if y[1] == 7]
[1]
>>> [x for x, y in enumerate(Tuple_list) if y[0] == 'kumquat']
[2]

Wie in den Kommentaren darauf hingewiesen, würde dies alle Übereinstimmungen erhalten. Um nur den ersten zu erhalten, können Sie Folgendes tun:

>>> [y[0] for y in Tuple_list].index('kumquat')
2

In den Kommentaren gibt es eine gute Diskussion über den Geschwindigkeitsunterschied zwischen allen veröffentlichten Lösungen. Ich bin vielleicht ein wenig voreingenommen, aber ich würde persönlich bei einem Einzeiler bleiben, da die Geschwindigkeit, über die wir sprechen, ziemlich unbedeutend ist, im Vergleich zu dem Erstellen von Funktionen und dem Importieren von Modulen für dieses Problem Von den Elementen können Sie sich die anderen Antworten ansehen, da diese schneller sind als die von mir angegebenen.

59

Diese Listenverständnisse sind nach einiger Zeit unordentlich.

Ich mag diesen pythonischen Ansatz:

from operator import itemgetter

def collect(l, index):
   return map(itemgetter(index), l)

# And now you can write this:
collect(Tuple_list,0).index("cherry")   # = 1
collect(Tuple_list,1).index("3")        # = 2

Wenn Sie benötigen, dass Ihr Code allesamt super performant ist:

# Stops iterating through the list as soon as it finds the value
def getIndexOfTuple(l, index, value):
    for pos,t in enumerate(l):
        if t[index] == value:
            return pos

    # Matches behavior of list.index
    raise ValueError("list.index(x): x not in list")

getIndexOfTuple(Tuple_list, 0, "cherry")   # = 1
26
Triptych

Eine Möglichkeit ist die Verwendung der Funktion itemgetter aus dem Modul operator:

import operator

f = operator.itemgetter(0)
print map(f, Tuple_list).index("cherry") # yields 1

Der Aufruf von itemgetter gibt eine Funktion zurück, die das Äquivalent von foo[0] für alles, was an sie übergeben wird, ausführt. Mit map wenden Sie diese Funktion dann auf jeden Tuple an und extrahieren die Informationen in eine neue Liste, in der Sie index wie üblich aufrufen.

map(f, Tuple_list)

ist äquivalent zu:

[f(Tuple_list[0]), f(Tuple_list[1]), ...etc]

was wiederum entspricht:

[Tuple_list[0][0], Tuple_list[1][0], Tuple_list[2][0]]

was gibt:

["pineapple", "cherry", ...etc]
9
Jarret Hardie

Sie können dies mit einem Listenverständnis und Index () tun.

Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11)]
[x[0] for x in Tuple_list].index("kumquat")
2
[x[1] for x in Tuple_list].index(7)
1
5
Alasdair

Ich würde dies als Kommentar zu Triptych schreiben, aber ich kann es noch nicht kommentieren, da es keine Bewertung gibt:

Unter Verwendung der Aufzählermethode zum Anpassen von Unterindizes in einer Liste von Tupeln.

li = [(1,2,3,4), (11,22,33,44), (111,222,333,444), ('a','b','c','d'),
        ('aa','bb','cc','dd'), ('aaa','bbb','ccc','ddd')]

# want pos of item having [22,44] in positions 1 and 3:

def getIndexOfTupleWithIndices(li, indices, vals):

    # if index is a Tuple of subindices to match against:
    for pos,k in enumerate(li):
        match = True
        for i in indices:
            if k[i] != vals[i]:
                match = False
                break;
        if (match):
            return pos

    # Matches behavior of list.index
    raise ValueError("list.index(x): x not in list")

idx = [1,3]
vals = [22,44]
print getIndexOfTupleWithIndices(li,idx,vals)    # = 1
idx = [0,1]
vals = ['a','b']
print getIndexOfTupleWithIndices(li,idx,vals)    # = 3
idx = [2,1]
vals = ['cc','bb']
print getIndexOfTupleWithIndices(li,idx,vals)    # = 4
2
Nisan.H

Inspiriert durch diese Frage fand ich das recht elegant:

>>> Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11)]
>>> next(i for i, t in enumerate(Tuple_list) if t[1] == 7)
1
>>> next(i for i, t in enumerate(Tuple_list) if t[0] == "kumquat")
2
2
Claudiu

ok, es könnte ein Fehler in vals(j) sein, die Korrektur lautet:

def getIndex(li,indices,vals):
for pos,k in enumerate(lista):
    match = True
    for i in indices:
        if k[i] != vals[indices.index(i)]:
            match = False
            break
    if(match):
        return pos
1
dulce ambrocio
Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11)]

def eachtuple(tupple, pos1, val):
    for e in tupple:
        if e == val:
            return True

for e in Tuple_list:
    if eachtuple(e, 1, 7) is True:
        print Tuple_list.index(e)

for e in Tuple_list:
    if eachtuple(e, 0, "kumquat") is True:
        print Tuple_list.index(e)
1

Ich denke, Folgendes ist nicht der beste Weg (Geschwindigkeits- und Eleganzprobleme), aber es könnte helfen: 

from collections import OrderedDict as od
t = [('pineapple', 5), ('cherry', 7), ('kumquat', 3), ('Plum', 11)]
list(od(t).keys()).index('kumquat')
2
list(od(t).values()).index(7)
7
# bonus :
od(t)['kumquat']
3

die Liste der Tupel mit 2 Mitgliedern kann direkt in geordnete Diktate umgewandelt werden.

0
jerome

List.index (x) von Python gibt den Index des ersten Vorkommens von x in der Liste zurück. So können wir Objekte übergeben, die durch Listenkomprimierung zurückgegeben werden, um deren Index zu ermitteln.

>>> Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11)]
>>> [Tuple_list.index(t) for t in Tuple_list if t[1] == 7]
[1]
>>> [Tuple_list.index(t) for t in Tuple_list if t[0] == 'kumquat']
[2]

Mit derselben Zeile können wir auch die Indexliste abrufen, falls mehrere übereinstimmende Elemente vorhanden sind.

>>> Tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("Plum", 11), ("banana", 7)]
>>> [Tuple_list.index(t) for t in Tuple_list if t[1] == 7]
[1, 4]
0
dspmeng
z = list(Zip(*Tuple_list))
z[1][z[0].index('persimon')]
0
eyaler

Kein Körper schlägt Lambdas vor?

Versuchen Sie es und funktioniert. Ich komme zu diesem Beitrag und suche Antwort. Ich habe das nicht gefunden, was mir gefällt, aber ich spüre ein Insingth: P

    l #[['rana', 1, 1], ['pato', 1, 1], ['perro', 1, 1]]

    map(lambda x:x[0], l).index("pato") #1 

Bearbeiten, um Beispiele hinzuzufügen: 

   l=[['rana', 1, 1], ['pato', 2, 1], ['perro', 1, 1], ['pato', 2, 2], ['pato', 2, 2]]

extrahieren Sie alle Elemente nach Bedingung: filter (lambda x: x [0] == "pato", l) # [["pato", 2, 1], ["pato", 2, 2], ["pato", 2, 2]]

extrahiere alle Artikel nach Bedingung mit Index:

    >>> filter(lambda x:x[1][0]=="pato", enumerate(l))
    [(1, ['pato', 2, 1]), (3, ['pato', 2, 2]), (4, ['pato', 2, 2])]
    >>> map(lambda x:x[1],_)
    [['pato', 2, 1], ['pato', 2, 2], ['pato', 2, 2]]

Hinweis: _ Variable funktioniert nur in interaktiven Interpreter-Dateien und normalen Textdateien _ muss explizit zugewiesen werden, dh _ = Filter (Lambda x: x [1] [0] == "pato", enumerate (l))

0
Wallebot