Le type de liste de Python a une méthode index () qui prend un paramètre et retourne l'index du premier élément de la liste correspondant au paramètre. Par exemple:
>>> some_list = ["Apple", "pear", "banana", "grape"]
>>> some_list.index("pear")
1
>>> some_list.index("grape")
3
Existe-t-il un moyen gracieux (idiomatique) d’étendre cela aux listes d’objets complexes, comme des n-uplets? Idéalement, j'aimerais 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 simplement une méthode hypothétique qui accepte un sous-index et une valeur, puis renvoie l'index de l'élément de liste avec la valeur donnée au niveau de ce sous-index. J'espère
Existe-t-il un moyen d'obtenir ce résultat général en utilisant des listes de compréhension ou des lambas ou quelque chose comme "en ligne"? Je pense que je pourrais écrire ma propre classe et méthode, mais je ne veux pas réinventer la roue si Python a déjà un moyen de le faire.
Que dis-tu de ça?
>>> 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, tous les matchs seraient obtenus. Pour obtenir le premier, vous pouvez faire:
>>> [y[0] for y in Tuple_list].index('kumquat')
2
Il y a une bonne discussion dans les commentaires sur la différence de vitesse entre toutes les solutions affichées. Je suis peut-être un peu partial, mais personnellement, je préfère m'en tenir à une ligne car la vitesse dont nous parlons est plutôt insignifiante par rapport à la création de fonctions et à l'importation de modules pour ce problème, vous voudrez peut-être examiner les autres réponses fournies, car elles sont plus rapides que ce que j’ai fourni.
Ces compréhensions de liste sont en désordre après un certain temps.
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
# 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
Une possibilité consiste à 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
renvoie une fonction qui fera l'équivalent de foo[0]
pour tout ce qui lui est transmis. En utilisant map
, vous appliquez ensuite cette fonction à chaque tuple en extrayant les informations dans une nouvelle liste, sur laquelle vous appelez ensuite index
normalement.
map(f, Tuple_list)
est équivalent à:
[f(Tuple_list[0]), f(Tuple_list[1]), ...etc]
ce qui équivaut à:
[Tuple_list[0][0], Tuple_list[1][0], Tuple_list[2][0]]
qui donne:
["pineapple", "cherry", ...etc]
Vous pouvez le faire avec une compréhension de liste et un index ()
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 placerais ceci comme un commentaire à Triptych, mais je ne peux pas encore commenter à cause du manque d'évaluation
Utilisation de la méthode énumératrice pour établir une correspondance sur des sous-indices dans une liste de tuples.
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 , j'ai trouvé cela assez é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, cela pourrait ê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)
Je suppose que ce qui suit n’est pas la meilleure façon de le faire (problèmes de vitesse et d’élégance), mais bon, cela 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
la liste des tuples avec 2 membres peut être convertie en dict ordonné directement, les structures de données sont en fait les mêmes, nous pouvons donc utiliser la méthode dict à la volée.
Le fichier list.index (x) de Python renvoie l'index de la première occurrence de x dans la liste. Nous pouvons donc passer les objets retournés par compression de 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 au cas où il y aurait 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]
z = list(Zip(*Tuple_list))
z[1][z[0].index('persimon')]
Aucun corps ne suggère de lambdas?
Y essayez ceci et fonctionne. Je viens à cette réponse de recherche post. Je n'ai pas trouvé que j'aimais, mais je me sens 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 articles par condition: filtre (lambda x: x [0] == "pato", l) # [['pato', 2, 1], ['pato', 2, 2], ['pato', 2, 2]]
extraire tous les articles par condition avec 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]]
Remarque: la variable _ ne fonctionne que dans l'interpréteur interactif y fichier de texte normal