2015-05-17 12 views
13

Sono bloccato capire questo fuori e mi chiedo se qualcuno mi potrebbe punto nella giusta direzione ...Python - Trova stessi valori in un elenco e di gruppo insieme una nuova lista

Da questo elenco:

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 

che sto cercando di creare:

L = [[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]] 

Qualsiasi valore che si trova ad essere la stessa è raggruppata in essa la propria sottolista. Ecco il mio tentativo finora, sto pensando che dovrei usare un ciclo while?

global n 

n = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] #Sorted list 
l = [] #Empty list to append values to 

def compare(val): 
    """ This function receives index values 
    from the n list (n[0] etc) """ 

    global valin 
    valin = val 

    global count 
    count = 0 

    for i in xrange(len(n)): 
     if valin == n[count]: # If the input value i.e. n[x] == n[iteration] 
      temp = valin, n[count] 
      l.append(temp) #append the values to a new list 
      count +=1 
     else: 
      count +=1 


for x in xrange (len(n)): 
    compare(n[x]) #pass the n[x] to compare function 
+0

* Ecco il mio tentativo finora * ... Si prega di citare se avete riscontrato problemi con il vostro codice. –

+0

Perché memorizzare tutti i numeri? Perché non comprimerlo semplicemente in un elenco di tuple contenenti due valori. Il numero stesso e il numero di volte in cui quel numero si verifica. –

risposta

12

qualcuno parla per N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1] otterrà [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]]

In altre parole, quando i numeri della lista non è in ordine o è una lista di disordine, non è disponibile.

Quindi ho una risposta migliore per risolvere questo problema.

from collections import Counter 

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 
C = Counter(N) 

print [ [k,]*v for k,v in C.items()] 
+0

Fantastico Tony! Mi sono imbattuto in problemi con l'indicizzazione utilizzando la soluzione itertools, quindi questo metodo ha funzionato bene perché non avevo bisogno di ordinare la lista in anticipo! Grazie ancora! – Siii

3

Si sta complicando questo.

Quello che si vuole fare è: per ogni valore, se è uguale all'ultimo valore, basta aggiungerlo all'elenco degli ultimi valori; altrimenti, crea una nuova lista. Si può tradurre che l'inglese direttamente a Python:

new_list = [] 
for value in old_list: 
    if new_list and new_list[-1][0] == value: 
     new_list[-1].append(value) 
    else: 
     new_list.append([value]) 

ci sono modi ancora più semplici per fare questo, se siete disposti a ottenere un po 'più astratto, per esempio, utilizzando le funzioni di raggruppamento in itertools. Ma questo dovrebbe essere facile da capire.


Se avete veramente bisogno di fare questo con un ciclo while, è possibile tradurre qualsiasi for ciclo in un ciclo while come questo:

for value in iterable: 
    do_stuff(value) 

iterator = iter(iterable) 
while True: 
    try: 
     value = next(iterator) 
    except StopIteration: 
     break 
    do_stuff(value) 

Oppure, se si conosce l'iterabile è una sequenza, è possibile utilizzare un po 'più semplice while ciclo:

index = 0 
while index < len(sequence): 
    value = sequence[index] 
    do_stuff(value) 
    index += 1 

Ma entrambi questi fanno il codice meno leggibile, meno Pythonic, più complicato, meno efficiente, più facile da sbagliare, ecc

+0

Davvero una bella risposta (mi piace la forza bruta), Ma puoi pensare ad un modo usando un ciclo 'while'? Nelle parole di OP * Sto pensando che dovrei usare un ciclo while? * –

+2

@BhargavRao: Beh, puoi sempre tradurre qualsiasi ciclo 'for' in un ciclo' while'. Ma perché vuoi? – abarnert

+0

Per questo problema il ciclo 'for' è più adatto. A differenza di C, le traduzioni py non sono così semplici, anche se sono piuttosto semplici. Ho solo chiesto di dare all'OP una buona idea del ciclo 'while' e delle sue complicazioni. D̶o̶ ̶c̶o̶n̶s̶i̶d̶e̶r̶ ̶d̶o̶i̶n̶g̶ ̶t̶h̶a̶t̶ ̶i̶n̶ ̶y̶o̶u̶r̶ ̶s̶p̶a̶r̶e̶ ̶t̶i̶m̶e̶ Bene buono lì :) –

3

È possibile utilizzare itertools.groupby insieme a un list comprehension

>>> l = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 
>>> [list(v) for k,v in itertools.groupby(l)] 
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]] 

Questo può essere assegnato alla variabile L come in

L = [list(v) for k,v in itertools.groupby(l)] 
26

Tenere calma e utilizzare itertools.groupby:

from itertools import groupby 

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 

print([list(j) for i, j in groupby(N)]) 

uscita:

[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]] 

Nota a margine: permettono di utilizzare variabile globale quando non bisogno a.

+0

Nota: l'elenco deve essere ordinato in base alla stessa chiave utilizzata da groupby per ottenere il risultato previsto nella domanda. Altrimenti, ad es. per 'N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 1]' otterrai '[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5], [1]] '. –

-1

Un'altra soluzione un po 'diversa, che non si basa su itertools:

#!/usr/bin/env python 

def group(items): 
    """ 
    groups a sorted list of integers into sublists based on the integer key 
    """ 
    if len(items) == 0: 
     return [] 

    grouped_items = [] 
    prev_item, rest_items = items[0], items[1:] 

    subgroup = [prev_item] 
    for item in rest_items: 
     if item != prev_item: 
      grouped_items.append(subgroup) 
      subgroup = [] 
     subgroup.append(item) 
     prev_item = item 

    grouped_items.append(subgroup) 
    return grouped_items 

print group([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]) 
# [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]] 
Problemi correlati