1

For lack of a better title, I want to find the most proper way to write (0, 0, 0, 0).

I am simply asking if (0,) * 4 is acceptable, and should it be done?

Are there any specific cases for this?

What if it could be either RGB, or RGBA? Should I do (0,) * n?

If this were in a loop, how significant would the overhead be?

Thanks.

Disclaimer: I am not asking for opinions, I am asking for a general consensus, or any written specification. Do not give your sole opinion without any support, or this post runs the risk of being closed due to going off-topic.

Jacob Birkett
  • 1,927
  • 3
  • 24
  • 49
  • 7
    "Do not give your sole opinion without any support, or this post runs the risk of being closed due to going off-topic.": it's the question that's off topic and gets closed, not the answers. – Jean-François Fabre Oct 05 '17 at 19:19
  • 1
    If the tuple will always contain `int` objects, then the semantics are equivalent, but if the objects are mutable, then the semantics aren't necessarily equivalent. – juanpa.arrivillaga Oct 05 '17 at 19:19
  • 4
    I'm risking an opinion: `*` operator is _designed_ for those cases (immutable contents), so go ahead – Jean-François Fabre Oct 05 '17 at 19:20
  • @Jean-François Fabre I did say *this post*, I just want to make sure that the answers don't end up getting my question flagged. Edit: Thanks for your real feedback (second comment). – Jacob Birkett Oct 05 '17 at 19:21
  • 1
    you're welcome. Your question is on-topic. If answers are bad, the answers will be flagged, not your question. People know how to make the difference, don't worry. – Jean-François Fabre Oct 05 '17 at 19:24

1 Answers1

4

If you had 100 zeroes to write in a tuple or list would you ask yourself this question?

Since the contents of the tuple are immutable elements, it's equivalent (it's faster to parse - see the end of the post - and the intent is clearer) to do (0,) * 4 instead of (0,0,0,0). It's beginning to become ridiculous for 2 elements but that's just my opinion :).

If the number increases it may save some precious debugging time because you missed one count/paste.

For mutable types don't do that!, but you can do a similar thing: ex:

  • [[] for _ in range(n)] for list of lists
  • tuple([] for _ in range(n)) for tuple of lists

Note that the (0,)*n form is definitely faster to parse. It's tricky to time such constructs because doing this naively skips the parsing part. But using evil eval helps in that case:

import time

n=100000

start_time = time.time()
for _ in range(n):
    eval("(0)*50")

print(time.time()-start_time)

fifty_zeros_tuple = "({})".format("0,"*50)  # generate (0,0,0,...) expression to pass to eval, not clocked to avoid bias

start_time = time.time()
for _ in range(n):
    eval(fifty_zeros_tuple)

print(time.time()-start_time)

no photo-finish on the results, (0,)*50 is many times faster:

0.764380931854248
5.553457021713257
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Also `timeit` can easily show that the exp: `python -m timeit 't = (0,)*4'` is almost the same as `python -m timeit 't = (0, 0, 0, 0)'` - so I think it's not arguable that using `(0,)*n` is not only fast but also practical! – coder Oct 05 '17 at 19:34
  • @coder thanks for benching this. I was expecting that, because parsing (0,0,0,0) is probably slower (more characters ;)) – Jean-François Fabre Oct 05 '17 at 19:35
  • Actually the speed seems to be the same for both cases but `(0,)*n` is a LOT more practical – coder Oct 05 '17 at 19:37
  • would be interesting to try with n=100. But I'm too lazy to type 0, 100 times (that's the whole point BTW :)) – Jean-François Fabre Oct 05 '17 at 19:38
  • I'm not sure that the parsing time is taken into account in timeit. – Jean-François Fabre Oct 05 '17 at 19:41
  • That's interesting..., I don't know that detail either, I just thought it would benchmark the time constructing the tuple – coder Oct 05 '17 at 19:44
  • I tried with a simple `time.time` and same thing. That cannot be properly benched because it's converted to bytecode before timing is done. So (0,)*100 takes more time to execute. see my edit, I found a way and I'm right :) – Jean-François Fabre Oct 05 '17 at 19:52