Получить список значений полей из Python sqlite3, а не кортежей, представляющих строки - PullRequest
39 голосов
/ 18 мая 2010

Раздражает, как модуль Python sqlite3 всегда возвращает список кортежей! Когда я запрашиваю один столбец, я бы предпочел получить простой список.

например. когда я выполню

SELECT somecol FROM sometable

и звоните

cursor.fetchall()

возвращает

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

но я бы лучше просто получил

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

Есть ли способ сделать это?

Ответы [ 6 ]

62 голосов
/ 16 апреля 2014

sqlite3.Connection имеет атрибут row_factory.

В документации указано, что:

Вы можете изменить этот атрибут на вызываемый, который принимает курсор и исходную строку в качестве кортежа и возвращает строку реального результата. Таким образом, вы можете реализовать более продвинутые способы возврата результатов, такие как возврат объекта, который также может обращаться к столбцам по имени.

Чтобы вернуть список отдельных значений из SELECT, например, id, вы можете назначить лямбду для 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.
14 голосов
/ 18 мая 2010
data=cursor.fetchall()
COLUMN = 0
column=[elt[COLUMN] for elt in data]

(Мое предыдущее предложение, column=zip(*data)[COLUMN], поднимает IndexError, если data - пустой кортеж. Напротив, приведенное выше понимание списка просто создает пустой список. В зависимости от вашей ситуации повышение IndexError может предпочтительнее, но я оставлю это на ваше усмотрение.)

9 голосов
/ 18 мая 2010

Вы на самом деле не хотите этого делать - все, что вы делаете по принципу использования zip или понимания списка, - это просто потребление циклов ЦП и использование памяти без значительного увеличения стоимости.Вам гораздо лучше справляться только с кортежами.

Что касается , почему возвращает кортежи, это потому, что это то, что Python DBD API 2.0 требует от fetchall.

5 голосов
/ 05 августа 2013

Я использую модуль панд для работы с табличным содержимым:

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

Список значений для столбца 'one' просто обозначается как:

df['one'].values

Вы даже можете использовать свой собственный индекс для ссылок на данные:

df0 = pd.DataFrame.from_records(cursor.fetchall(), columns=['Time','Serie1','Serie2'],index='Time')
0 голосов
/ 14 апреля 2019
zlist = []

tupls = c.fetchall()

for tup in tupls:

    t = str(tup).replace("('","").replace("',)","")

    zlist.append(t)

Теперь вам не нужно иметь дело с кортежами, пандами или чем-то из вышеперечисленного, которое не сработало.

0 голосов
/ 18 мая 2010

учетная запись для случая, когда cursor.fetchall () возвращает пустой список:

try:
    columnlist = list(zip(*cursor.fetchall())[COLUMN_INDEX])
except IndexError:
    columnlist = []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...