19

Please consider the following example

>>import redis
>>redis_db_url = '127.0.0.1'
>>r = redis.StrictRedis(host = redis_db_url,port = 6379,db = 0)
>>r.sadd('a',1)
>>r.sadd('a',2)
>>r.sadd('a',3)
>>r.smembers('a')

[+] output: set(['1', '3', '2'])

>>r.sadd('a',set([3,4]))
>>r.smembers('a')

[+] output: set(['1', '3', '2', 'set([3, 4])'])

 >>r.sadd('a',[3,4])
 >>r.smember('a')

[+] set(['1', '[3, 4]', '3', '2', 'set([3, 4])'])

According to the official documentation in https://redis-py.readthedocs.org/en/latest/ sadd(name, *values) Add value(s) to set name

So is it a bug or I am missing something ?

Sourav Sarkar
  • 406
  • 1
  • 5
  • 14

2 Answers2

40

When you see the syntax *values in an argument list, it means the function takes a variable number of arguments.

Therefore, call it as

r.sadd('a', 1, 2, 3)

You can pass an iterable by using the splat operator to unpack it:

r.sadd('a', *set([3, 4]))

or

r.sadd('a', *[3, 4])
nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • I could be wrong, but i don't think you have to cast as a `set` before unpacking – Seaux Mar 01 '17 at 06:29
  • 1
    No, you don't, but I was following the example in the author's question. In this case the inline syntax is just a shortcut for indicating that you can do this with an arbitrary set (or indeed, an arbitrary iterable). – nneonneo Mar 01 '17 at 23:04
  • 1
    And really, on any recent Python you can just do `*{3, 4}` which is the native syntax for set literals, eliminating the "cast" altogether. – nneonneo Mar 01 '17 at 23:05
  • 1
    Agreed. I just wanted to clarify the point because I didn't want readers to think you had to cast to `set` for use in `sadd` or something. I'd recommend editing the answer to separate out the declaration of the iterable (set) in another line or just remove the casting all together. – Seaux Mar 02 '17 at 18:56
3

Consider the following:

r.sadd('a', 1, 2, 3)

That should do the trick.

Itamar Haber
  • 47,336
  • 7
  • 91
  • 117