2009-05-19 16 views
10

Jeśli mam listę w Pythonie jakJak obliczyć największą liczbę powtórzeń na liście?

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

Jak obliczyć największą liczbę powtórzeń dla każdego elementu? W tym przypadku 2 powtarza się maksymalnie 4 razy, a 1 powtarza się maksymalnie 3 razy.

Czy istnieje sposób, aby to zrobić, ale także zarejestrować indeks, od którego rozpoczyna się najdłuższy bieg?

+0

Wygląda na to, że szukasz najdłuższego przebiegu na liście; możesz edytować swoje pytanie, aby to wyjaśnić. – las3rjock

+2

W szczególności najdłuższy bieg każdego numeru – Sparr

+0

Tak Sparr jest poprawny. Czy istnieje sposób, aby to zrobić, ale także zarejestrować indeks, od którego rozpoczyna się najdłuższy bieg? – hekevintran

Odpowiedz

42

użytkowania groupby, IT Group elementy według wartości:

from itertools import groupby 
group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]) 
print max(group, key=lambda k: len(list(k[1]))) 

A oto kod w akcji:

>>> group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]) 
>>> print max(group, key=lambda k: len(list(k[1]))) 
(2, <itertools._grouper object at 0xb779f1cc>) 
>>> group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3]) 
>>> print max(group, key=lambda k: len(list(k[1]))) 
(3, <itertools._grouper object at 0xb7df95ec>) 

Z dokumentacji Pythona:

Operacja of groupby() jest podobny do filtra uniq w systemie Unix. To generuje przerwę lub nową grupę każdy czasu wartość funkcji klucza zmienia

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B 
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D 

Jeśli chcesz także indeks najdłuższego biegu można wykonać następujące czynności:

group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3]) 
result = [] 
index = 0 
for k, g in group: 
    length = len(list(g)) 
    result.append((k, length, index)) 
    index += length 

print max(result, key=lambda a:a[1]) 
+0

+1 - "groupby" jest do tego dostosowany. –

+0

Czy istnieje sposób, aby to zrobić, a także zarejestrować indeks, w którym rozpoczął się najdłuższy bieg? Dzięki! – hekevintran

+0

Uaktualniłem odpowiedź za pomocą rozwiązania, aby uzyskać indeks również –

0

Kod ten wydaje się działać:

l = [1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1] 
previous = None 

# value/repetition pair 
greatest = (-1, -1) 
reps = 1 

for e in l: 
    if e == previous: 
     reps += 1 
    else: 
     if reps > greatest[1]: 
      greatest = (previous, reps) 

     previous = e 
     reps = 1 

if reps > greatest[1]: 
    greatest = (previous, reps) 

print greatest 
+0

+1 za pokonanie mnie. – geowa4

+3

to nie jest to, co OP pyta – SilentGhost

+0

OP dał nawet przypadek testowy ... który twoje wyniki nie pasują ... –

0

użyję HashMap elementu, aby przeciwdziałać.

Za każdym razem, gdy zobaczysz sukcesję "kluczową", zwiększ jej wartość licznika. Jeśli trafisz nowy element, ustaw licznik na 1 i kontynuuj. Na końcu tego wyszukiwania liniowego powinieneś mieć maksymalną liczbę sukcesji dla każdego numeru.

3

Przeprowadź pętlę na liście, śledź bieżącą liczbę, ile razy została ona powtórzona i porównaj ją z najczęściej powtarzanym numerem.

Counts={} 
Current=0 
Current_Count=0 
LIST = [1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1] 
for i in LIST: 
    if Current == i: 
     Current_Count++ 
    else: 
     Current_Count=1 
     Current=i 
    if Current_Count>Counts[i]: 
     Counts[i]=Current_Count 
print Counts 
1

Jeśli chcesz go tylko dla dowolnego elementu (tj. Elementu z większością powtórzeń), możesz użyć:

def f((v, l, m), x): 
    nl = l+1 if x==v else 1 
    return (x, nl, max(m,nl)) 

maxrep = reduce(f, l, (0,0,0))[2]; 

To liczy tylko ciągłe powtórzenia (Wynik dla [1,2,2,2,1,2] będzie 3) i będzie zapisywany tylko element z maksymalną liczbą.

Edit: Wykonana definicja fa bit krócej ...

+0

Wydaje się być podobnym do wielu rzeczy z Perla? ;) –

1

To jest moje rozwiązanie:

def longest_repetition(l): 
    if l == []: 
     return None 

    element = l[0] 
    new = [] 
    lar = [] 

    for e in l:    
     if e == element: 
      new.append(e) 
     else: 
      if len(new) > len(lar): 
       lar = new 
      new = [] 
      new.append(e) 
      element = e 
    if len(new) > len(lar): 
     lar = new  
    return lar[0] 
1

-Można zrobić nową kopię listy, ale z unikalnymi wartościami i odpowiedni hitów lista.

-Po otrzymaniu listy Maksymalna liczba trafień i uzyskania z indeksu najbardziej powtarzanego przedmiotu.

oldlist = ["A", "B", "E", "C","A", "C","D","A", "E"] 
newlist=[] 
hits=[] 
for i in range(len(oldlist)): 
    if oldlist[i] in newlist: 
     hits[newlist.index(oldlist[i])]+= 1 
    else: 
     newlist.append(oldlist[i]) 
     hits.append(1); 
#find the most repeated item 
temp_max_hits=max(hits) 
temp_max_hits_index=hits.index(temp_max_hits) 
print(newlist[temp_max_hits_index]) 
print(temp_max_hits) 

Ale nie wiem, czy to jest najszybszy sposób, aby to zrobić, czy istnieje szybsze rozwiązanie. Jeśli uważasz, że istnieje szybsze lub bardziej wydajne rozwiązanie, prosimy o poinformowanie nas.

Powiązane problemy