2012-04-01 26 views
8

Tôi có một danh sách:Python max với cùng một số trường hợp

hello = ['1', '1', '2', '1', '2', '2', '7'] 

tôi muốn để hiển thị các yếu tố phổ biến nhất của danh sách, vì vậy tôi đã sử dụng:

m = max(set(hello), key=hello.count) 

Tuy nhiên, tôi nhận ra rằng có thể có hai phần tử của danh sách xảy ra cùng một tần số, như là số 1 và số 2 trong danh sách ở trên. Max chỉ xuất ra trường hợp đầu tiên của phần tử tần số tối đa.

Loại lệnh nào có thể kiểm tra danh sách để xem liệu hai thành phần có cả số lượng tối đa các trường hợp không và nếu có, hãy xuất cả hai thành phần đó? Tôi đang bị lạc ở đây.

Trả lời

13

Sử dụng một cách tiếp cận tương tự như hiện tại của bạn, trước tiên bạn sẽ tìm thấy những số tối đa và sau đó nhìn cho mỗi mục với count rằng:

>>> m = max(map(hello.count, hello)) 
>>> set(x for x in hello if hello.count(x) == m) 
set(['1', '2']) 

Ngoài ra, bạn có thể sử dụng Counter lớp đẹp, có thể được sử dụng để có hiệu quả, tốt, đếm thứ:

>>> hello = ['1', '1', '2', '1', '2', '2', '7'] 
>>> from collections import Counter 
>>> c = Counter(hello) 
>>> c 
Counter({'1': 3, '2': 3, '7': 1}) 
>>> common = c.most_common() 
>>> common 
[('1', 3), ('2', 3), ('7', 1)] 

Sau đó, bạn có thể sử dụng một danh sách hiểu biết để có được tất cả những yếu tố có tính tối đa:

>>> set(x for x, count in common if count == common[0][1]) 
set(['1', '2']) 
+0

gì về thời gian khi có 3 lặp đi lặp lại con số, như [ '1', '1', '2', '2', '8', '7', '7'] ... kịch bản của bạn sẽ không hoạt động cho điều đó. Cảm ơn, nếu không thì giải pháp là tốt. –

+0

@james: Không thể tạo lại, nó trả về 'bộ (['1', '2', '7'])' cho tôi với cả hai đoạn mã. –

+0

À vâng, không vấn đề gì, nó hoạt động rất tốt cho tôi bây giờ. Cảm ơn nhiều. –

2
from collections import Counter 

def myFunction(myDict): 
    myMax = 0 # Keep track of the max frequence 
    myResult = [] # A list for return 

    for key in myDict: 
     print('The key is', key, ', The count is', myDict[key]) 
     print('My max is:', myMax) 
     # Finding out the max frequence 
     if myDict[key] >= myMax: 
      if myDict[key] == myMax: 
       myMax = myDict[key] 
       myResult.append(key) 
      # Case when it is greater than, we will delete and append 
      else: 
       myMax = myDict[key] 
       del myResult[:] 
       myResult.append(key) 
    return myResult 

foo = ['1', '1', '5', '2', '1', '6', '7', '10', '2', '2'] 
myCount = Counter(foo) 
print(myCount) 

print(myFunction(myCount)) 

Output:

The list: ['1', '1', '5', '2', '1', '6', '7', '10', '2', '2'] 
Counter({'1': 3, '2': 3, '10': 1, '5': 1, '7': 1, '6': 1}) 
The key is 10 , The count is 1 
My max is: 0 
The key is 1 , The count is 3 
My max is: 1 
The key is 2 , The count is 3 
My max is: 3 
The key is 5 , The count is 1 
My max is: 3 
The key is 7 , The count is 1 
My max is: 3 
The key is 6 , The count is 1 
My max is: 3 
['1', '2'] 

tôi đã viết chương trình đơn giản này, tôi nghĩ rằng nó cũng có thể làm việc. Tôi đã không nhận thức được chức năng most_common() cho đến khi tôi thực hiện tìm kiếm. Tôi nghĩ rằng điều này sẽ trả về nhiều phần tử thường xuyên nhất, nó hoạt động bằng cách so sánh phần tử thường xuyên tối đa, khi tôi thấy một phần tử thường xuyên hơn, nó sẽ xóa danh sách kết quả và nối nó một lần; hoặc nếu nó là cùng một tần số, nó chỉ đơn giản là phụ thêm vào nó. Và tiếp tục đi cho đến khi toàn bộ Counter được lặp lại.

+0

Đây là một ví dụ tuyệt vời! Nó cho thấy làm thế nào để làm điều này cho mình nếu bạn không chỉ tìm kiếm cách dễ nhất. – agf

+2

Tôi cũng học được điều gì đó, tôi đã học được cách hàm 'most_common()' hoạt động, và đánh dấu nó trong trường hợp trong tương lai tôi cần hàm đó một lần nữa. Vì vậy, nó là giành chiến thắng-thắng cho tất cả chúng ta, cổ vũ! – George

3

Edit: giải pháp thay đổi

>>> from collections import Counter 
>>> from itertools import groupby 
>>> hello = ['1', '1', '2', '1', '2', '2', '7'] 
>>> max_count, max_nums = next(groupby(Counter(hello).most_common(), 
           lambda x: x[1])) 
>>> print [num for num, count in max_nums] 
['1', '2'] 
+0

1, giải pháp tốt đẹp và sạch sẽ. Dòng cuối cùng có thể được đơn giản hóa thành 'd [max (d)]' :) –

+1

Cảm ơn, bây giờ nó trông đẹp hơn: D – jamylak

+0

Vấn đề với phương pháp này là O (n ** 2). 'sequence.count' là O (n) và bạn làm điều đó một lần cho mỗi mục trong chuỗi.Phương thức 'Counter', hoặc tương đương được mã hóa bằng tay, là O (n) - số hoạt động cho mỗi mục độc lập với số lượng các mục trong chuỗi. – agf