2012-04-30 4 views
6

Per due liste,lista partita in python: ottenere indici di un sotto-elenco in una lista più ampia

a = [1, 2, 9, 3, 8, ...] (no duplicate values in a, but a is very big) 
b = [1, 9, 1,...]   (set(b) is a subset of set(a), 1<<len(b)<<len(a)) 

indices = get_indices_of_a(a, b) 

come lasciare get_indices_of_a ritorno indices = [0, 2, 0,...] con array(a)[indices] = b? C'è un metodo più veloce rispetto all'utilizzo di a.index, che richiede troppo tempo?

Fare b un insieme è un metodo rapido di corrispondenza elenchi e ritorno indici (vedi compare two lists in python and return indices of matched values), ma perderà l'indice del secondo 1 così come la sequenza degli indici in questo caso.

risposta

12

Procedimento veloce (quando a è una grande lista) sarebbe utilizzando un dict per mappare i valori in a agli indici:

>>> index_dict = dict((value, idx) for idx,value in enumerate(a)) 
>>> [index_dict[x] for x in b] 
[0, 2, 0] 

Questo richiederà tempo lineare nel caso medio, rispetto all'utilizzo a.index cui prenderebbe il tempo quadratico

+0

+1. Questa è una buona risposta per elenchi di grandi dimensioni in cui ridurrà drasticamente il tempo necessario; naturalmente, in piccole liste, la creazione del testo richiederà più tempo di quanto non salverà. Dato il commento del richiedente sulla mia risposta, sembra che siano coinvolte grandi liste, quindi questa è la risposta desiderata. –

7

Presumendo che stiamo lavorando con le liste più piccole, questo è facile come:

>>> a = [1, 2, 9, 3, 8] 
>>> b = [1, 9, 1] 
>>> [a.index(item) for item in b] 
[0, 2, 0] 

sulle liste più grandi, questo diventerà piuttosto costoso.

(Se ci sono duplicati, la prima occorrenza sarà sempre quella a cui si fa riferimento nell'elenco risultante, se not set(b) <= set(a), si otterrà un errore ValueError).

+0

Grazie mille! Non ci sono duplicati, ma a è molto grande, e b non è piccolo neanche se len (b) << len (a). Usando a.index (item) stai facendo una ricerca in a per ogni valore in b ... c'è un metodo più veloce? – user1342516

+0

@ user1342516 Sì, vedere [risposta di Interjay] (http://stackoverflow.com/a/10385786/722121). –

+0

puoi aggiungere questo alla tua soluzione per rimuovere la situazione ValueError: [a.index (articolo) per oggetto in b se articolo in a] –