2014-11-28 18 views
7

Sto usando heapq per ottenere gli ultimi elementi dalla lista degli elenchi. Il programma che ho scritto è qui sotto.Come posso ottenere n elenchi più grandi da un elenco di elenchi in 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 

Voglio solo i primi 20 elementi. Quindi invece di ordinare ho pensato di usare un mucchio. L'errore che sto ottenendo è,

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 

Posso sapere perché sto ottenendo l'errore e come risolverlo. C'è qualche proprietà dell'utilizzo di heapq che mi manca.

+0

qual è la lunghezza delle righe? sono quelli stessi? – Kasramvd

+0

Sì, sono la dimensione 4. Tutti loro. – WannaBeCoder

risposta

2

enumerate() restituisce un iterable oltre 2-tuple. Pertanto l'accesso a x[2] nel secondo esempio sarà sempre fuori intervallo (gli unici indici validi sono 0 e 1).

Per rendere il secondo esempio equivalente al primo, si dovrebbe essere di passaggio allrows direttamente invece di utilizzare enumerate():

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

Se è necessario per preservare gli indici originali, enumerate() è la strada da percorrere. Tuttavia, è necessario anche un ulteriore livello di riferimento indiretto nella funzione chiave:

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

L'ho capito ora. L'enumeratore restituisce una tupla. così x [1] [2]. Volevo anche gli indici, quindi stavo usando enumerare. – WannaBeCoder

2

Grazie NPE per l'illuminazione Il problema, come una risposta alternativa è possibile concatenare tutti i tuoi file con itertools.chain() e ottenere top 20 elementi con l'ordinamento, che hanno più di prestazioni rispetto heapq:

from itertools import chain 

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

I nlargest() e nsmallest() funzioni sono più appropriato se si sta cercando di trovare un numero relativamente piccolo di elementi. Se stai semplicemente cercando di trovare il singolo più piccolo o l'elemento più grande (N=1), è più veloce usare min() e max(). Allo stesso modo, se N è circa la stessa dimensione della raccolta stessa, è solitamente più veloce ordinarla prima e prendere una porzione (ad esempio, utilizzare sorted(items)[:N] o sorted(items)[-N:]).

+0

Sarebbe bello vedere alcuni benchmark per sostenere le dichiarazioni di prestazione (queste cose sono spesso piene di sorprese). – NPE

+0

@kasra OP non sta chiedendo la soluzione su come ottenere i primi 20 elementi, sta chiedendo l'errore che sta ottenendo. –

+0

@VishnuUpadhyay sì, anche se questo non era il mio qsn. Non lo sapevo fino ad ora. Quindi grazie Kasara. – WannaBeCoder

Problemi correlati