2010-05-18 13 views
29

È fastidioso come il modulo sqlite3 di Python restituisca sempre un elenco di tuple! Quando interrogherò una singola colonna, preferirei ottenere una lista semplice.Ottieni un elenco di valori di campo da sqlite3 di Python, non tuple che rappresentano righe

ad es. quando eseguo

SELECT somecol FROM sometable 

e chiamo

cursor.fetchall() 

restituisce

[(u'one',), (u'two',), (u'three',)] 

ma preferirei solo ottenere

[u'one', u'two', u'three'] 

C'è un modo per fare questo?

risposta

7

non si vuole veramente fare questo - tutto quello che fare le linee di utilizzo di zip o di una lista di comprensione è solo mangiare cicli di CPU e succhiare memoria senza aggiungere un valore significativo. Sei molto meglio servito solo a trattare con le tuple.

Per quanto riguarda il motivo per cui ritorna tuple, è perché questo è ciò che il Python DBD API 2.0 richiede da fetchall.

12
data=cursor.fetchall() 
COLUMN = 0 
column=[elt[COLUMN] for elt in data] 

(Il mio suggerimento precedente, column=zip(*data)[COLUMN], solleva un IndexError se data è una tupla vuota. Al contrario, la lista di comprensione di cui sopra crea solo un elenco vuoto. A seconda della situazione, sollevando un IndexError può essere preferibile, ma lascio a voi decidere)

+0

Idiom o espediente? È robusto? Per quali valori di len (foo) è zip (* foo) garantito di non andare a splat? –

+0

perfetto. 'columnlist = list (zip (* cursor.fetchall()) [COLUMN_INDEX])' –

+0

Jeremiah Penso che dovresti prestare attenzione all'avvertimento di ~ unutbu! –

-1

conto nel caso in cui cursor.fetchall() restituisce una lista vuota:.

try: 
    columnlist = list(zip(*cursor.fetchall())[COLUMN_INDEX]) 
except IndexError: 
    columnlist = [] 
4

Io uso il modulo panda a che fare con la tabella-simile tenore:

df = pd.DataFrame(cursor.fetchall(), columns=['one','two']) 

L'elenco dei valori per la colonna 'uno' è semplicemente A riferiti come:

df['one'].values 

È anche possibile utilizzare il proprio indice per il riferimento dei dati:

df0 = pd.DataFrame.from_records(cursor.fetchall(), columns=['Time','Serie1','Serie2'],index='Time') 
38

sqlite3.Connection ha un attributo row_factory.

La documentazione afferma che:

È possibile modificare questo attributo per un richiamabile che accetta il cursore e la riga originale come tuple e tornerà il vero riga del risultato. In questo modo, puoi implementare metodi più avanzati di restituzione dei risultati, come restituire un oggetto che può anche accedere alle colonne per nome.

per restituire un elenco di valori singoli da un SELECT, quale un id, è possibile assegnare un lambda a row_factory che restituisce il primo valore indicizzato in ogni fila; per esempio:

import sqlite3 as db 

conn = db.connect('my.db') 
conn.row_factory = lambda cursor, row: row[0] 
c = conn.cursor() 
ids = c.execute('SELECT id FROM users').fetchall() 

Questo produce qualcosa di simile:

[1, 2, 3, 4, 5, 6] # etc. 
+2

semplice e migliore. Non so perché non è accettato come risposta! –

+3

Grazie :) Ho risposto a questa domanda molto tempo dopo che la domanda era stata postata (e risolta). Per quanto riguarda accettato o no - Sono solo contento che aiuta! –

+0

Grazie per aver postato. Mi ha aiutato solo pochi minuti fa! –

Problemi correlati