2015-10-13 11 views
5

Attualmente, voglio trovare la struttura dati corretta per soddisfare il seguente requisito.Struttura dati per rappresentare più chiavi equivalenti in set in Python?

Ci sono più array con elemento disordinata, per esempio,

[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]

Dopo l'elaborazione di tali dati, il risultato è,

[1, 2], [2, 2, 3], [2], [1, 2, 3]

con elemento ordinato in ogni matrice e filtro gli array duplicati.

Qui sono i miei pensieri:

  • Struttura dei dati Set(Arrays)? - Non riuscito. Sembra che ci sia un solo array nella build-in set

    set([])

  • Struttura dei dati Array(Sets)? - Non riuscito. Tuttavia, non ci sono elementi duplicati nel build-in set. Voglio sapere se esiste una struttura dati come multiset in C++ all'interno di Python?

+0

BTW, quelli sembrano normali liste di Python, non Python [array] (https: // docs. python.org/3/library/array.html)s; il popolare pacchetto di terze parti Numpy fornisce anche i tipi [array] (http://docs.scipy.org/doc/numpy/user/basics.creation.html). –

+0

map (lista, set (tupla (sort (i)) per i in a)), se a è l'input – Vineesh

+0

@Vineesh: non inserire le risposte nei commenti. –

risposta

5

Trasforma la vostra lista di tupla (quindi può essere un elemento di set), poi di nuovo alla lista.

>>> [list(i) for i in set([tuple(sorted(i)) for i in a])] 
[[1, 2], [2], [2, 2, 3], [1, 2, 3]] 
2

Prova questo:

[list(i) for i in set(map(tuple, a))] 

EDIT: Supponendo che list è già ordinato. Grazie a @ PM2RING per ricordarmelo. In caso contrario, quindi aggiungere questa riga sopra

a = [sorted(i) for i in a] 

Grazie ancora a @ PM2RING: uno di linea

[list(i) for i in set(map(tuple, (sorted(i) for i in a)))] 

Demo

2

No Python, non ha un built-in multiset; l'equivalente più vicino nei moduli standard è collections.Counter, che è un tipo di dizionario. Un contatore può essere adatto alle tue esigenze, ma è difficile dirlo senza più contesto.


Nota che le serie fanno non appannaggio ordine di aggiunta.Se è necessario per preservare l'ordinamento iniziale delle liste, si può fare ciò che si vuole in questo modo:

data = [[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]] 

a = set() 
outlist = [] 
for s in data: 
    t = tuple(sorted(s)) 
    if t not in a: 
     a.add(t) 
     outlist.append(list(t)) 

print(outlist) 

uscita

[[1, 2], [2, 2, 3], [2], [1, 2, 3]] 

Se il numero di liste di ingresso è abbastanza piccolo si don' t necessario il set (e l'elenco < -> conversioni di tupla), basta provare l'appartenenza a outlist. Tuttavia, ciò non è efficiente per gli elenchi di input più grandi poiché esegue una ricerca lineare nell'elenco.

+1

Controlla la mia risposta per un de-dupe più efficiente senza quella ricerca lineare – wim

4
lst = [[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]] 
map(list, set(map(tuple, map(sorted, lst))) 

uscita:

[[1, 2], [2], [2, 2, 3], [1, 2, 3]] 
+3

Non so, bambini in questi giorni, e la loro fantastica programmazione funzionale. :) –

+0

LOL! So che Guido vorrebbe fortemente obiettare :-) – haavee

+0

normalmente odio la mappa, ma questa è una bella! – wim

2

Alcune delle soluzioni attualmente qui stanno distruggendo l'ordinazione. Non sono sicuro se questo è importante per voi o no, ma qui è una versione che conserva ordinamento originale:

>>> from collections import OrderedDict 
>>> A = [[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]] 
>>> [list(k) for k in OrderedDict.fromkeys(tuple(sorted(a)) for a in A)] 
[[1, 2], [2, 2, 3], [2], [1, 2, 3]] 
Problemi correlati