2012-03-30 19 views
7

Dato un elenco, è necessario restituire un elenco di elenchi di elementi univoci. Sto cercando di vedere se c'è un modo più Pythonic di quello che mi si avvicinò con:Elenchi univoci da un elenco

def unique_lists(l): 
    m = {} 
    for x in l: 
     m[x] = (m[x] if m.get(x) != None else []) + [x] 
    return [x for x in m.values()]  

print(unique_lists([1,2,2,3,4,5,5,5,6,7,8,8,9])) 

uscita:

[[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
+0

Grazie per Counter, soluzioni GroupBy e defaultdict! Ho imparato qualcosa di nuovo oggi. –

risposta

9
>>> L=[1,2,2,3,4,5,5,5,6,7,8,8,9] 
>>> from collections import Counter 
>>> [[k]*v for k,v in Counter(L).items()] 
[[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
+1

Originariamente ho pubblicato una soluzione che era più breve di una riga semplicemente usando il metodo di conteggio incorporato della lista, ma gnibbler rende l'eccellente punto che list.count() è O (n), rendendo il mio algoritmo O (n^2). +1 –

+3

Non c'è motivo per cui la creazione del "Contatore" non possa essere piegata nella comprensione della lista qui: '[[k] * v per k, v in Counter (L) .items()]'. –

+0

@Karl, sono d'accordo, non penso sia meno leggibile –

2

Utilizzando dict default.

>>> from collections import defaultdict 
>>> b = defaultdict(list) 
>>> a = [1,2,2,3,4,5,5,5,6,7,8,8,9] 
>>> for x in a: 
...  b[x].append(x) 
... 
>>> b.values() 
[[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
0

trovo la configurazione in funzione di set() utile molto spesso:

lst=[1,2,2,3,4,5,5,5,6,7,8,8,9] 

def all_eq_elms(lst, elm): 
    while True: 
     try: 
      yield lst.pop(lst.index(elm)) 
     except: 
      break 

[[e for e in all_eq_elms(lst,elm)] for elm in set(lst)] 

Out[43]: [[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
Problemi correlati