2009-05-12 18 views
5

Voglio trovare la posizione (s) di un elemento specifico in un elenco di elenchi. Dovrebbe restituire un elenco di tuple, in cui ogni tupla rappresenta gli indici per un'istanza specifica dell'elemento. Per esempio:Come posso trovare le posizioni di un oggetto in un elenco di elenchi Python?

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

quello che dovrebbe essere restituito per il seguente elenco: [[ '1', '1', '1', '1'], [ '7', '0', '4'] ]? – SilentGhost

+0

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

+3

Eviterei di usare il nome variabile "elenco", poiché questo è un tipo built-in – Noah

risposta

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

Questo è un buon punto di partenza. Presumibilmente si dispone di una sorta di classe come la

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

che in questo caso avrebbe lasciato che dici

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

Si noti che in entrambi i casi si otterrà un'eccezione se il tuo obiettivo non è in ogni uno dei tuoi sottolisti. La domanda non specifica se questo è il comportamento desiderato.

+0

Non credo che questo si adatta alla domanda. L'argomento di 'getPosition' è un elemento (o un sottoelemento) mentre il valore restituito è una posizione, non il contrario. –

+0

Sì, l'ho letto male in un primo momento, ma da allora ho risolto il mio codice per fare la cosa giusta. –

5

Sembra che si desideri, per un elenco di sottoliste e un determinato articolo, restituire un elenco di coppie in cui ciascuna coppia è (l'indice della sottolista, l'indice dell'elemento all'interno della sottolista). È possibile farlo usando list comprehensions e Python di costruito in funzione di enumerate(): risposta vedere @ di scarabocchio sopra/sotto:

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

Modifica.

+0

e +1 per l'icona ResEdit :) – Noah

+0

Questo si interromperà se l'elemento non è in ogni sottolista. Vedi il mio suggerimento qui sotto. O al di sopra, alla fine, spero :-) - scrible 53 secondi fa – Arkady

+0

Sì, ho intenzione di -1 per @ motivo di scrible - questo genererà un'eccezione se a un sottolista manca un elemento. –

2

Se non si desidera un'eccezione se l'elemento non è presente nell'elenco, provare questo. Anche come generatore perché sono fantastici e versatili.

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

Se si desidera qualcosa che saranno entrambi

  • trovare i duplicati e
  • maniglia liste annidate (elenchi delle liste di liste di ...)

si può fare qualcosa come il seguente:

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

Testing questo:

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

Qualche tempo fa ho scritto una libreria per Python per fare la lista di corrispondenza che si adatterebbe il disegno di legge abbastanza bene. Ha usato i token?, + E * come caratteri jolly, dove? significa un singolo atomo, + è uno-o-più avido, e * è uno-o-più avido. Per esempio:

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

scaricarlo qui: http://www.artfulcode.net/wp-content/uploads/2008/12/matching.zip

0

Ecco una versione senza provare ..tranne, restituendo un iteratore e che per

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

rendimenti

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

Si noti che quanto segue sembra anche un po 'più veloce: def getPosition1 (l, val): per row_nb, r in enumerate (l): per col_nb, _ in enumerate (elemento per oggetto in r se articolo == val): yield row_nb, col_nb – odwl

0

Il più strainghtforward e probabilmente il modo più lento da eseguire sarebbe:

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

Ecco un altro metodo dritto in avanti quello non usa i generatori.

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

sembra scarabocchio o scrible ha cambiato nome? Altrimenti chi è il referenziamento @apaidnerd? – emmagras

Problemi correlati