2009-05-19 28 views
10

Nếu tôi có một danh sách bằng Python nhưLàm thế nào để bạn tính toán số lần lặp lại lớn nhất trong một danh sách?

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

Làm thế nào để tính toán số lượng lớn nhất của lặp đi lặp lại cho bất kỳ yếu tố? Trong trường hợp này, 2 được lặp lại tối đa 4 lần và 1 được lặp lại tối đa 3 lần.

Có cách nào để làm điều này nhưng cũng ghi lại chỉ mục mà tại đó thời gian dài nhất bắt đầu?

+0

Có vẻ như bạn đang tìm kiếm lần chạy dài nhất trong danh sách; bạn có thể muốn chỉnh sửa câu hỏi của mình để làm rõ điều đó. – las3rjock

+2

Cụ thể là lần chạy dài nhất của mỗi số – Sparr

+0

Có Sparr đúng. Có cách nào để làm điều này nhưng cũng ghi lại các chỉ số mà chạy dài nhất bắt đầu? – hekevintran

Trả lời

42

Sử dụng groupby, nó yếu tố nhóm theo giá trị:

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

Và đây là mã trong hành động:

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

Từ tài liệu python:

Các hoạt động của groupby() tương tự vào bộ lọc uniq trong Unix. Nó tạo bảng phân hoặc nhóm mới mỗi thời điểm đó giá trị của hàm then chốt thay đổi

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

Nếu bạn cũng muốn các chỉ số của thời gian lâu nhất bạn có thể làm như sau:

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' được thiết kế riêng cho việc này. –

+0

Có cách nào để làm điều này và cũng ghi lại chỉ mục mà tại đó thời gian dài nhất bắt đầu? Cảm ơn! – hekevintran

+0

Tôi đã cập nhật câu trả lời với một giải pháp để có được chỉ mục cũng như –

0

Mã này dường như làm việc:

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 để đánh bại tôi. – geowa4

+3

đó không phải là những gì OP yêu cầu – SilentGhost

+0

OP thậm chí đã đưa ra trường hợp kiểm tra ... mà kết quả của bạn không khớp ... –

0

Tôi muốn sử dụng một hashmap mặt hàng để chống lại.

Mỗi khi bạn nhìn thấy lần kế thừa 'khóa', hãy tăng giá trị bộ đếm của nó. Nếu bạn nhấn một phần tử mới, hãy đặt bộ đếm thành 1 và tiếp tục. Ở cuối tìm kiếm tuyến tính này, bạn sẽ có số lần kế tiếp tối đa cho mỗi số.

3

Lặp qua danh sách, theo dõi số hiện tại, số lần lặp lại, và so sánh với số lần bạn thấy số đó lặp lại nhiều lần.

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

Nếu bạn muốn nó chỉ với bất kỳ yếu tố nào (tức là yếu tố có nhiều lần lặp lại nhất), bạn có thể sử dụng:

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

Điều này chỉ đếm lặp lại liên tục (Kết quả cho [1,2,2,2,1,2] sẽ là 3) và chỉ ghi lại phần tử với số tối đa.

Sửa: định nghĩa Made của fa cắn ngắn ...

+0

Có vẻ như rất nhiều công cụ của Perl? ;) –

1

Đây là giải pháp của tôi:

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

-Bạn có thể làm cho bản sao mới của danh sách, nhưng với các giá trị độc đáo và một hit tương ứng danh sách.

- Sau đó nhận danh sách Số lần truy cập tối đa và nhận được từ chỉ mục đó là mục được lặp lại nhiều nhất của bạn.

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) 

Nhưng tôi không biết đây là cách nhanh nhất để làm điều đó hoặc có giải pháp nhanh hơn. Nếu bạn nghĩ rằng có giải pháp nhanh hơn hoặc hiệu quả hơn, vui lòng thông báo cho chúng tôi.

Các vấn đề liên quan