从Python的sqlite3中获取字段值列表,而不是表示行的元组

2024-09-28 17:24:50 发布

您现在位置:Python中文网/ 问答频道 /正文

Python的^{}模块总是返回一个元组列表,这真令人恼火!当我查询一个列时,我希望得到一个简单的列表。

例如,当我执行

SELECT somecol FROM sometable

打电话来

cursor.fetchall()

它又回来了

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

但我宁愿

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

有办法吗?


Tags: 模块from列表selectonecursorthree元组
3条回答

sqlite3.Connection有一个^{}属性。

文件规定:

You can change this attribute to a callable that accepts the cursor and the original row as a tuple and will return the real result row. This way, you can implement more advanced ways of returning results, such as returning an object that can also access columns by name.

要从SELECT返回单个值的列表,例如id,可以将lambda赋给row_factory,它返回每行中的第一个索引值;例如:

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

这会产生如下结果:

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

您还可以直接在游标对象本身上设置row_factory。实际上,如果在创建游标之前未在连接上设置row_factory,则必须在游标上设置row_factory

c = conn.cursor()
c.row_factory = lambda cursor, row: {'foo': row[0]}

在游标对象的生存期内,您可以在任意点重新定义row_factory,也可以使用None取消设置行工厂以返回基于元组的默认结果:

c.row_factory = None
c.execute('SELECT id FROM users').fetchall() # [(1,), (2,), (3,)] etc.

你真的不想这么做-你所做的任何事情,沿着使用zip或列表理解的路线,只是吃CPU周期和吸吮内存,而没有增加重要的价值。你最好是处理元组。

至于为什么返回元组,这是因为Python DBD API 2.0需要fetchall返回元组。

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

(我之前的建议,column=zip(*data)[COLUMN],如果data是空元组,则引发一个IndexError。相反,上面的列表理解只会创建一个空列表。根据你的情况,提出一个IndexError可能更好,但我将留给你决定。)

相关问题 更多 >