2013-04-06 7 views
16

sto memorizzazione di una lista in Redis come questo:Redis: Come fare il parsing di conseguenza lista

redis.lpush('foo', [1,2,3,4,5,6,7,8,9]) 

E poi ho la lista di nuovo in questo modo:

redis.lrange('foo', 0, -1) 

e ottengo qualcosa di simile this:

[b'[1, 2, 3, 4, 5, 6, 7, 8, 9]'] 

Come posso convertire questo in vero elenco Python?

Inoltre, non vedo nulla definito in RESPONSE_CALLBACKS che può essere d'aiuto? Mi sto perdendo qualcosa?

Una possibile soluzione (che a mio parere fa schifo) può essere:

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

Ok, così ho ottenuto la soluzione.

In realtà, la funzione lpush si aspetta che tutti gli elementi della lista essere passati come argomenti e non come un unico elenco. La firma funzione dalla fonte Redis-py rende chiaro ...

def lpush(self, name, *values): 
    "Push ``values`` onto the head of the list ``name``" 
    return self.execute_command('LPUSH', name, *values) 

Quello che sto facendo qui sopra è inviare un unico elenco come argomento, che viene poi inviato a Redis come un singolo elemento.

dovrei disimballaggio lista invece come suggerito la risposta:

redis.lpush('foo', *[1,2,3,4,5,6,7,8,9]) 

che restituisce il risultato mi aspetto ...

redis.lrange('foo', 0, -1) 
[b'9', b'8', b'7', b'6', b'5', b'4', b'3', b'2', b'1'] 

risposta

15

Penso che tu sia sbattere contro semantica simile alla distinzione tra list.append() e list.extend(). So che questo funziona per me:

myredis.lpush('foo', *[1,2,3,4]) 

... notare l'operatore * (mappa-over) anteponendo la lista!

+0

Esatto, è la differenza tra lpush() essere passati due argomenti (la chiave e un singolo oggetto che sembra essere una lista) e passare gli oggetti "n + 1" (chiave e ogni oggetto * dall'interno * dell'elenco). Questo è il comportamento "var args" o "n-ary" in Python. Per il tipo di lista integrata useremmo "extend()" piuttosto che "append()". –

0
import json 
r = [b'[1, 2, 3, 4, 5, 6, 7, 8, 9]'] 
rstr = r[0] 
res_list = json.loads(rstr) 
+0

Questa risposta non ha senso. Sta usando gli elenchi di Redis con le operazioni * PUSH e LRANGE Redis. La codifica JSON di un'opzione Python avrebbe senso solo se si utilizza il tipo scalare Redis con SET e altre operazioni simili. Darebbe un'occhiata alla coerenza fornita da Redis per * POP e operazioni correlate su elementi dell'elenco; ed essere costretti a SET e OTTENERE l'intera lista con ogni operazione. –

+0

a volte è meglio essere specifici. – ashim888

+0

ha funzionato per me;) – Juan

-2

realtà questa domanda duplica questo: How to push a whole sequence to redis in Python. Il problema e la sua soluzione è assolutamente lo stesso: per ottenere correttamente i dati dell'elenco, dovremmo inserire in modo corretto prima di.

+0

Perché non il contrario? Ad ogni modo, per favore non postare commenti come questo come risposte. Con un po 'più di reputazione, sarai in grado di inviare commenti e segnalare domande come duplicati. –

2

Un altro modo: è possibile utilizzare la libreria 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 

converte tipi pitone a REDIS tipi e viceversa.Quindi, anche se tu avessi una lista annidata, avrebbe funzionato:

>>> 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'> 

Disclaimer: Ho scritto la biblioteca. Ecco il codice: https://github.com/seperman/redisworks

Problemi correlati