2009-05-19 5 views
10

Если у меня есть список в Python, какКак вы рассчитываете наибольшее количество повторений в списке?

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

Как вычислить наибольшее число повторов для любого элемента? В этом случае 2 повторяется максимум 4 раза, а 1 повторяется максимум 3 раза.

Есть ли способ сделать это, но также записать индекс, в котором начался самый длинный запуск?

+0

Звучит так, что вы ищете самый длинный пробег в списке; вы можете отредактировать свой вопрос, чтобы это было ясно. – las3rjock

+2

В частности, самый длинный пробег каждого номера – Sparr

+0

Да, это правильно. Есть ли способ сделать это, но также записать индекс, в котором начался самый длинный запуск? – hekevintran

ответ

42

Использование groupby, это элементы группы по значению:

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]))) 

А вот код в действии:

>>> 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>) 

Из питона документации:

Операцию groupby() аналогичен в uniq-фильтр в Unix. Он генерирует излома или новую группу каждый время значение ключевой функции изменения

# [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 

Если вы также хотите индекс самого длинного пробега вы можете сделать следующее:

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' специально для этого. –

+0

Есть ли способ сделать это, а также записать индекс, в котором начался самый длинный запуск? Благодаря! – hekevintran

+0

Я обновил ответ с помощью решения, чтобы получить индекс, а также –

0

Этот код, кажется, работает:

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 за избиение меня. – geowa4

+3

Это не то, что ОП задает – SilentGhost

+0

ОП даже дал тестовый пример ... который не соответствует вашим результатам ... –

0

Я хотел бы использовать HashMap пункта противостоять.

Каждый раз, когда вы видите последовательность «ключ», увеличивайте его значение счетчика. Если вы нажмете новый элемент, установите счетчик равным 1 и продолжайте движение. В конце этого линейного поиска вы должны иметь максимальное количество подряд для каждого номера.

3

Прокрутите список, отследите текущий номер, сколько раз он был повторен, и сравните это с тем, как вы видели это число.

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

Если вы хотите получить только любой элемент (т. Е. Элемент с наибольшим количеством повторений), вы можете использовать:

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]; 

Это только отсчет непрерывных повторений (результат для [1,2,2,2,1,2] будет 3) и записывает только элемент с максимальным числом.

Редактировать: Сделано определение фа немного короче ...

+0

Кажется, похоже на много вещей в Perl? ;) –

1

Это мое решение:

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

, Вы можете сделать новую копию списка, но с уникальными значениями и соответствующими хитами список.

-После получения списка Максимальных ударов и получения от него индекса вашего наиболее повторяющегося элемента.

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) 

Но я не знаю, это самый быстрый способ сделать это или есть более быстрое решение. Если вы считаете, что есть более быстрое или эффективное решение, сообщите нам об этом.

Смежные вопросы