2009-05-12 5 views
5

Je veux trouver l'emplacement (s) d'un élément spécifique dans une liste de listes. Il devrait retourner une liste de tuples, où chaque tuple représente les index pour une instance spécifique de l'élément. Par exemple:Comment puis-je trouver les emplacements d'un élément dans une liste de listes Python?

list = [['1', '2', '4', '6'], ['7', '0', '1', '4']] 
getPosition('1') #returns [(0, 0), (1, 2)] 
and getPosition('7') #returns [(1,0)] 
+0

ce qui devrait être renvoyé pour la liste suivante: [[ '1', '1', '1', '1'], [ '7', '0', '4'] ]? – SilentGhost

+0

@SilentGhost - Je dirais: [(0,0), (0,1), (0,2), (0,3)] –

+3

J'éviterais d'utiliser le nom de variable "list", car c'est un type intégré – Noah

Répondre

2
def get_positions(xs, target): 
    return [(i,e.index(target)) for i,e in enumerate(xs)] 

C'est un bon point de départ. Je présume que vous avez une sorte de classe telle que

class SomeClass: 
    def __init__(self): 
     self.xs = [['1','2','4','6'], ['7','0','1','4']] 

    def get_positions(self, target): 
     return [(i,e.index(target)) for i,e in enumerate(self.xs)] 

qui dans ce cas serait vous laisser dire

model = SomeClass() 
model.get_position(1) # returns [(0,0), (1,2)] 

Notez que dans les deux cas, vous aurez une exception si votre cible est pas dans tous les un de vos sous-listes. La question ne précise pas si c'est le comportement souhaité.

+0

Je ne crois pas que cela corresponde à la question. L'argument de 'getPosition' est un élément (ou sous-élément) alors que la valeur retournée est une position, pas l'inverse. –

+0

Oui, je l'ai mal lu au début, mais j'ai depuis corrigé mon code pour faire la bonne chose. –

5

Il semble que vous souhaitez, pour une liste de sous-listes et un élément donné, retourner une liste de paires où chaque paire est (l'index de la sous-liste, l'index de l'article dans la sous-liste). Vous pouvez le faire en utilisant list comprehensions et Python construit en fonction enumerate():

def getPosition(list, item): 
    return [(i, sublist.index(item)) for i, sublist in enumerate(list)] 

Edit: Voir la réponse de @ gribouillis ci-dessus/au-dessous.

+0

et +1 pour l'icône ResEdit :) – Noah

+0

Cela se casse si l'élément n'est pas dans chaque sous-liste. Voir ma suggestion ci-dessous. Ou au-dessus, finalement, j'espère :-) - scrible il y a 53 secondes – Arkady

+0

Ouais, je vais -1 pour la raison de @ scrible - ceci jettera une exception si une sous-liste manque un élément. –

2

Si vous ne voulez pas d'exception si l'élément ne figure pas dans la liste, essayez ceci. Aussi en tant que générateur, car ils sont cool et polyvalent.

xs = [['1', '2', '4', '6'], ['7', '0', '1', '4']] 
def get_positions(xs, item): 
    for i, xt in enumerate(xs): 
     try: # trying beats checking 
      yield (i, xt.index(item)) 
     except ValueError: 
      pass 

print list(get_positions(xs, '1')) 
print list(get_positions(xs, '6')) 

# Edit for fun: The one-line version, without try: 

get_positions2 = lambda xs,item: ((i,xt.index(item)) for i, xt in enumerate(xs) if item in xt) 

print list(get_positions2(xs, '1')) 
print list(get_positions2(xs, '6')) 
7

Si vous voulez quelque chose qui à la fois

  • trouver des doublons et
  • gérer des listes imbriquées (listes de listes de listes de ...)

vous pouvez faire quelque chose comme le suivant:

def get_positions(xs, item): 
    if isinstance(xs, list): 
     for i, it in enumerate(xs): 
      for pos in get_positions(it, item): 
       yield (i,) + pos 
    elif xs == item: 
     yield() 

Test ceci:

>>> xs = [['1', '2', '4', '6'], 
...  ['7', '0', '1', '4'], 
...  [ [ '0', '1', '1'], ['1']] 
...  ] 
>>> print list(get_positions(xs, '1')) 
[(0, 0), (1, 2), (2, 0, 1), (2, 0, 2), (2, 1, 0)] 
0

Il y a quelque temps j'ai écrit une bibliothèque Python pour faire la liste de correspondance qui correspondre à la facture assez bien. Il a utilisé les jetons?, +, Et * comme jokers, où? signifie un seul atome, + est un un-ou-plus non gourmand, et * est gourmand en un ou plusieurs. Par exemple:

from matching import match 

match(['?', 2, 3, '*'], [1, 2, 3, 4, 5]) 
=> [1, [4, 5]] 

match([1, 2, 3], [1, 2, 4]) 
=> MatchError: broken at 4 

match([1, [2, 3, '*']], [1, [2, 3, 4]]) 
=> [[4]] 

match([1, [2, 3, '*']], [1, [2, 3, 4]], True) 
=> [1, 2, 3, [4]] 

Téléchargez-le ici: http://www.artfulcode.net/wp-content/uploads/2008/12/matching.zip

0

Voici une version sans essayer ..sauf, retournant un itérateur et que pour

[['1', '1', '1', '1'], ['7', '0', '4']] 

retours

[(0, 0), (0, 1), (0, 2), (0, 3)] 


def getPosition1(l, val): 
    for row_nb, r in enumerate(l): 
     for col_nb in (x for x in xrange(len(r)) if r[x] == val): 
     yield row_nb, col_nb 
+0

Notez que ce qui suit semble même un peu plus vite: def getPosition1 (l, val): pour row_nb, r dans enumerate (l): pour col_nb, _ dans enumerate (point pour objet r si l'article == val): rendement row_nb, col_nb – odwl

0

Le plus strainghtforward et probablement la plus lente façon de le faire serait:

>>> value = '1' 
    >>> l = [['1', '2', '3', '4'], ['3', '4', '5', '1']] 
    >>> m = [] 
    >>> for i in range(len(l)): 
    ... for j in range(len(l[i])): 
    ... if l[i][j] == value: 
    ... m.append((i,j)) 
    ... 
    >>> m 
    [(0, 0), (1, 3)] 
0

Voici une autre méthode avant droite cela n'utilise pas de générateurs.

def getPosition(lists,item): 
    positions = [] 
    for i,li in enumerate(lists): 
     j = -1 
     try: 
      while True: 
       j = li.index(item,j+1) 
       positions.append((i,j)) 
     except ValueError: 
      pass 
    return positions 

l = [['1', '2', '4', '6'], ['7', '0', '1', '4']] 
getPosition(l,'1') #returns [(0, 0), (1, 2)] 
getPosition(l,'9') # returns [] 

l = [['1', '1', '1', '1'], ['7', '0', '1', '4']] 
getPosition(l,'1') #returns [(0, 0), (0, 1), (0,2), (0,3), (1,2)] 
3
def getPosition(list, item): 
    return [(i, sublist.index(item)) for i, sublist in enumerate(list) 
                 if item in sublist] 
+1

il semble scribble ou scrible a changé de nom? Sinon, qui est le référencement de @apaidnerd? – emmagras

Questions connexes