Question

type de liste de python a une méthode index () qui prend un paramètre et renvoie l'index du premier élément dans la liste correspondant au paramètre. Par exemple:

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

Y at-il une manière gracieuse (idiomatiques) d'étendre aux listes d'objets complexes, comme tuples? Idéalement, je voudrais pouvoir faire quelque chose comme ceci:

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

getIndexOfTuple () est juste une méthode hypothétique qui accepte un sous-indice et une valeur, puis retourne l'index de l'élément de la liste avec la valeur donnée à ce sous-indice. J'espère

Y at-il un moyen de parvenir à ce résultat général, l'utilisation de la liste ou compréhensions lambas ou quelque chose « en ligne » comme ça? Je pense que je pourrais écrire ma propre classe et de méthode, mais je ne veux pas réinventer la roue si Python a déjà une façon de le faire.

Était-ce utile?

La solution

Comment cela?

>>> 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]

Comme indiqué dans les commentaires, ce serait obtenir tous les matches. Pour obtenir seulement la première, vous pouvez faire:

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

Il y a une bonne discussion dans les commentaires à la différence de vitesse entre toutes les solutions affichées. Je peux être un peu partial, mais je personnellement en tenir à une seule ligne comme la vitesse dont nous parlons est assez insignifiante par rapport à la création de fonctions et importer des modules pour ce problème, mais si vous avez décidé de le faire à une très grande quantité des éléments que vous pouvez regarder les autres réponses fournies, car ils sont plus rapides que ce que je fournis.

Autres conseils

Ces listes sont compréhensions en désordre après un certain temps.

J'aime cette approche Pythonic:

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

Si vous avez besoin de votre code pour être tous super performant:

# 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

Il est possible d'utiliser la fonction itemgetter du module operator :

import operator

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

L'appel à itemgetter retourne une fonction qui fera l'équivalent de foo[0] pour tout ce qui lui est passé. En utilisant map, vous appliquez ensuite cette fonction à chaque tuple, extraire les informations dans une nouvelle liste, sur laquelle vous appelez ensuite index comme normal.

map(f, tuple_list)

est équivalent à:

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

ce qui est équivalent à:

[tuple_list[0][0], tuple_list[1][0], tuple_list[2][0]]

Ce qui donne:

["pineapple", "cherry", ...etc]

Vous pouvez le faire avec une compréhension et index liste ()

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

Je mettrais cela comme un commentaire à Triptyque, mais je ne peux pas commenter encore en raison du manque de note:

En utilisant la méthode de recenseur pour correspondre à des sous-indices dans une liste de tuples. par exemple.

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

Inspiré par cette question , je trouve cela très élégant:

>>> 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

ok, il est peut-être une erreur dans vals(j), la correction est:

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
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)
z = list(zip(*tuple_list))
z[1][z[0].index('persimon')]

Aucun organisme suggère lambdas?

Y essayez et fonctionne. Je viens à cette réponse post recherche. Je ne suis pas trouvé que je l'aime, mais je me sens un insingth: P

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

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

Modifier pour ajouter des exemples:

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

extraire tous les éléments en fonction des conditions:         filtre (lambda x: x [0] == "pato", l) # [[ 'pato', 2, 1], [ 'pato', 2, 2], [ 'pato', 2, 2]]

extraire tous les éléments en fonction des conditions d'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]]

Note: _ Variable ne fonctionne que dans interpréteur interactif y fichier texte normal _ besoin explicti assigner, par exemple _ = filtre (lambda x: x [1] [0] == "pato", énumèrent (l))

Le list.index de Python (x) retourne l'index de la première occurrence de x dans la liste. Ainsi, nous pouvons passer des objets retournés par la compression de la liste pour obtenir leur index.

>>> 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]

Avec la même ligne, nous pouvons également obtenir la liste des index dans le cas où il y a plusieurs éléments correspondants.

>>> 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]

Je suppose que ce qui suit est pas la meilleure façon de le faire (problèmes de vitesse et élégance), mais bien, il pourrait aider à:

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

Liste des tuples avec 2 membres peuvent être convertis directement dict ordonnée, les structures de données sont en fait les mêmes, donc nous pouvons utiliser la méthode dict à la volée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top