2010-05-18 30 views
29

Thật khó chịu khi mô-đun sqlite3 của Python luôn trả về một danh sách các bộ dữ liệu! Khi tôi đang truy vấn một cột, tôi muốn có danh sách đơn giản hơn.Lấy danh sách các giá trị trường từ sqlite3 của Python, không phải tuples đại diện cho các hàng

ví dụ: khi tôi thực hiện

SELECT somecol FROM sometable 

và gọi

cursor.fetchall() 

nó trả

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

nhưng tôi chỉ muốn có được

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

Có cách nào để làm điều này?

Trả lời

7

bạn không thực sự muốn làm điều này - bất cứ điều gì bạn làm theo các dòng của việc sử dụng zip hoặc một danh sách hiểu là chỉ ăn chu kỳ CPU và hút bộ nhớ mà không cần thêm giá trị đáng kể. Bạn đang phục vụ tốt hơn chỉ cần đối phó với các bộ dữ liệu.

Đối với lý do tại sao nó trả về bộ dữ liệu, đó là vì đó là số Python DBD API 2.0 yêu cầu từ fetchall.

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

(đề nghị trước đây của tôi, column=zip(*data)[COLUMN], đặt ra một IndexError nếu data là một tuple trống. Ngược lại, danh sách hiểu trên chỉ tạo ra một danh sách trống. Tùy thuộc vào tình hình của bạn, nâng cao một IndexError có thể thích hợp hơn, nhưng tôi sẽ rời khỏi đó để bạn quyết định)

+0

Idiom hay mánh lới quảng cáo? Nó có mạnh không? Đối với những giá trị của len (foo) là zip (* foo) đảm bảo không đi splat? –

+0

hoàn hảo. 'columnlist = list (zip (* cursor.fetchall()) [COLUMN_INDEX])' –

+0

Jeremiah Tôi nghĩ bạn nên chú ý đến cảnh báo của ~ unutbu! –

-1

tài khoản cho các trường hợp cursor.fetchall() trả về một danh sách trống:.

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

tôi sử dụng các mô-đun gấu trúc để đối phó với nội dung bàn như:

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

Danh sách các giá trị cho cột 'one' chỉ đơn giản là-xăng như:

df['one'].values 

Bạn thậm chí có thể sử dụng chỉ mục của riêng bạn để tham chiếu dữ liệu:

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

sqlite3.Connection có thuộc tính row_factory.

Các tài liệu nói rằng:

Bạn có thể thay đổi thuộc tính này cho một người có thể được gọi là chấp nhận con trỏ và hàng gốc như một tuple và sẽ trả lại hàng kết quả thực sự. Bằng cách này, bạn có thể triển khai các cách trả về nâng cao hơn, chẳng hạn như trả về một đối tượng cũng có thể truy cập các cột theo tên.

Để trả về một danh sách các giá trị duy nhất từ ​​một SELECT, chẳng hạn như một id, bạn có thể gán một lambda để row_factory mà trả về giá trị chỉ mục đầu tiên trong mỗi hàng; ví dụ:

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

Điều này mang lại một cái gì đó như:

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

đơn giản và tốt nhất. Tôi không biết tại sao nó không được chấp nhận như một câu trả lời! –

+3

Cảm ơn :) Tôi đã trả lời câu hỏi này một thời gian dài sau khi câu hỏi được đăng lần đầu tiên (và giải quyết). Đối với chấp nhận hay không - Tôi chỉ vui vì nó giúp! –

+0

Cảm ơn bạn đã đăng bài. Nó chỉ giúp tôi vài phút trước! –

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