Redis: как разобрать результат списка
Я храню список в Redis следующим образом:
redis.lpush('foo', [1,2,3,4,5,6,7,8,9])
И затем я верну список:
redis.lrange('foo', 0, -1)
и я получаю что-то вроде этого:
[b'[1, 2, 3, 4, 5, 6, 7, 8, 9]']
Как я могу преобразовать это в реальный список Python?
Кроме того, я не вижу ничего определенного в RESPONSE_CALLBACKS
, который может помочь? Я что-то пропустил?
Возможное решение (которое, на мой взгляд, отстой) может быть:
result = redis.lrange('foo',0, -1)[0].decode()
result = result.strip('[]')
result = result.split(', ')
# lastly, if you know all your items in the list are integers
result = [int(x) for x in result]
UPDATE
Хорошо, поэтому я получил решение.
На самом деле функция lpush
ожидает, что все элементы списка будут переданы как аргументы, а NOT - как один список. Подпись функции от источника redis-py дает понять...
def lpush(self, name, *values):
"Push ``values`` onto the head of the list ``name``"
return self.execute_command('LPUSH', name, *values)
То, что я делаю выше, отправляет единственный список в качестве аргумента, который затем отправляется redis как элемент SINGLE.
Я должен распаковать список вместо этого, как это было предложено в ответе:
redis.lpush('foo', *[1,2,3,4,5,6,7,8,9])
который возвращает результат, который я ожидаю...
redis.lrange('foo', 0, -1)
[b'9', b'8', b'7', b'6', b'5', b'4', b'3', b'2', b'1']
Ответы
Ответ 1
Я думаю, что вы сталкиваетесь с семантикой, которая похожа на различие между list.append() и list.extend(). Я знаю, что это работает для меня:
myredis.lpush('foo', *[1,2,3,4])
... обратите внимание на оператор * (map-over), префиксный список!
Ответ 2
Другой способ: вы можете использовать библиотеку RedisWorks
.
pip install redisworks
>>> from redisworks import Root
>>> root = Root()
>>> root.foo = [1,2,3,4,5,6,7,8,9] # saves it to Redis as a list
...
>>> print(root.foo) # loads it from Redis later
Он преобразует типы python в типы Redis и наоборот. Поэтому, даже если у вас есть вложенный список, это сработало бы:
>>> root.sides = [10, [1, 2]] # saves it as list in Redis.
>>> print(root.sides) # loads it from Redis
[10, [1, 2]]
>>> type(root.sides[1])
<class 'list'>
Отказ от ответственности: я написал библиотеку. Вот код: https://github.com/seperman/redisworks
Ответ 3
import json
r = [b'[1, 2, 3, 4, 5, 6, 7, 8, 9]']
rstr = r[0]
res_list = json.loads(rstr)
Ответ 4
На самом деле этот вопрос дублирует это:
Как перенести целую последовательность на redis в Python. Проблема и ее решение абсолютно одинаковы - чтобы правильно получить данные списка, мы должны направить их правильно.