2014-11-28 37 views
7

Tôi đang sử dụng heapq để lấy các phần tử nlargest từ danh sách các danh sách. Chương trình tôi đã viết là dưới đây.Làm cách nào để lấy n danh sách lớn nhất từ ​​danh sách các danh sách trong python

import csv 
import heapq 
f = open("E:/output.csv","r") 
read = csv.reader(f) 

allrows = [row for row in read] 

for i in xrange(0,2): 
    print allrows[i] 

allrows.sort(key=lambda x: x[2]) #this is working properly 
it=heapq.nlargest(20,enumerate(allrows),key=lambda x:x[2]) #error 

Tôi chỉ muốn 20 yếu tố hàng đầu. Vì vậy, thay vì phân loại tôi nghĩ đến việc sử dụng một đống. Lỗi tôi nhận được là,

Traceback (most recent call last): 
File "D:\eclipse_progs\DaDv\IMDB\Assignment1.py", line 42, in <module> 
    it=heapq.nlargest(2,enumerate(allrows),key=lambda x:x[2]) 
File "C:\Python27\lib\heapq.py", line 470, in nlargest 
    result = _nlargest(n, it) 
File "D:\eclipse_progs\DaDv\IMDB\Assignment1.py", line 42, in <lambda> 
    it=heapq.nlargest(2,enumerate(allrows),key=lambda x:x[2]) 
IndexError: tuple index out of range 

Tôi có thể biết tại sao tôi gặp lỗi và cách giải quyết. Có bất kỳ tài sản của việc sử dụng heapq tôi đang mất tích.

+0

chiều dài của các hàng của bạn là bao nhiêu? có giống nhau không? – Kasramvd

+0

Vâng, chúng có kích thước 4. Tất cả chúng. – WannaBeCoder

Trả lời

2

enumerate() trả về giá trị có thể lặp lại trên 2 bộ. Do đó, việc truy cập x[2] trong ví dụ thứ hai của bạn sẽ luôn nằm ngoài phạm vi (chỉ có các chỉ số hợp lệ là 0 và 1).

Để làm ví dụ thứ hai tương đương với đầu tiên, bạn nên đi qua allrows trực tiếp thay vì sử dụng enumerate():

it = heapq.nlargest(20, allrows, key=lambda x:x[2]) 

Nếu bạn cần phải duy trì các chỉ số ban đầu, enumerate() là con đường để đi. Tuy nhiên, bạn cũng cần một mức độ thêm về mình trong hàm chính:

it = heapq.nlargest(20, enumerate(allrows), key=lambda x:x[1][2]) 
         ^^^^^^^^^       ^^^ 
+0

Tôi nhận được nó ngay bây giờ. Th điều tra viên trả về một tuple. vì vậy x [1] [2]. Tôi cũng muốn các chỉ số vì vậy tôi đã sử dụng liệt kê. – WannaBeCoder

2

Cảm ơn NPE để thắp sáng các vấn đề, Như một câu trả lời khác bạn có thể nối tất cả hàng của bạn với itertools.chain() và nhận được yếu tố top 20 với sắp xếp, mà có hiệu suất hơn heapq:

from itertools import chain 

sorted(chain(*allrows))[-20:] 

các nlargest()nsmallest() chức năng thích hợp nhất nếu bạn đang cố gắng tìm thấy một số lượng tương đối nhỏ các hạng mục. Nếu bạn chỉ đơn giản là cố gắng tìm đơn lẻ nhỏ nhất hoặc mục lớn nhất (N=1), sử dụng nhanh hơn min()max() sẽ nhanh hơn. Tương tự, nếu N có kích thước tương tự là với bản thân bộ sưu tập, thì thường nhanh hơn để sắp xếp nó trước và lấy một lát (tức là, sử dụng sorted(items)[:N] hoặc sorted(items)[-N:]).

+0

Thật tuyệt khi thấy một số điểm chuẩn để sao lưu các tuyên bố về hiệu suất (những điều này thường đầy những bất ngờ). – NPE

+0

@kasra OP không hỏi giải pháp làm thế nào để có được 20 yếu tố hàng đầu, anh ta đang yêu cầu lỗi mà anh ta đang nhận được. –

+0

@VishnuUpadhyay có, mặc dù đây không phải là qsn của tôi. Tôi đã không biết về điều này cho đến bây giờ. Vì vậy, cảm ơn bạn Kasara. – WannaBeCoder

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