What to pass when passing arguments where a list or tuple is required?
Question: Which of the following should I use and why?

    
    
    import numpy as np
    a = np.zeros([2, 3])
    b = np.zeros((2, 3))
    

There are many cases where you can pass arguments in either way, I just wonder
if one is more Pythonic or if there are other reasons where one should be
preferred over the other.

I looked at [this question](http://stackoverflow.com/questions/8900166/whats-
the-difference-between-lists-enclosed-by-square-brackets-and-parentheses)
where people tried to explain the difference between a tuple and a list.
That's not what I'm interested in, unless there are reasons I should care
which I ignore of course!

UPDATE:

Although numpy was used as an example this pertains generally to python. A non
numpy example is as follows:

    
    
    a = max([1, 2, 3, 5, 4])
    b = max((1, 2, 3, 5, 4))
    

I'm not editing the above because some answers use numpy in their explanation


Answer: I'm answering this in the context of passing a literal iterable to a
constructor or function beyond which the type does not matter. If you need to
pass in a hashable argument, you need a tuple. If you'll need it mutated, pass
in a list (so that you don't add tuples to tuples thereby multiplying the
creation of objects.)

The answer to your question is that the better option varies situationally.
Here's the tradeoffs.

Starting with `list` type, which is mutable, it preallocates memory for future
extension:

    
    
    a = np.zeros([2, 3])
    

**Pro** : It's easily readable.

**Con** : It wastes memory, and it's less performant.

Next, the `tuple` type, which is immutable. It doesn't need to preallocate
memory for future extension, because it can't be extended.

    
    
    b = np.zeros((2, 3))
    

**Pro** : It uses minimal memory, and it's more performant.

**Con** : It's a little less readable.

My preference is to pass tuple literals where memory is a consideration, for
example, long-running scripts that will be used by lots of people. On the
other hand, when I'm using an interactive interpreter, I prefer to pass lists
because they're a bit more readable, the contrast between the square brackets
and the parenthesis makes for easy visual parsing.

You should only care about performance in a function, where the code is
compiled to bytecode:

    
    
    >>> min(timeit.repeat('foo()', 'def foo(): return (0, 1)'))
    0.080030765042010898
    >>> min(timeit.repeat('foo()', 'def foo(): return [0, 1]'))
    0.17389221549683498
    

Finally, note that the performance consideration will be dwarfed by other
considerations. You use Python for speed of development, not for speed of
algorithmic implementation. If you use a bad algorithm, your performance will
be much worse. It's also very performant in many respects as well. I consider
this only important insomuch as it may scale, if it can ameliorate heavily
used processes from dying a death of a thousand cuts.

