In many places, (1,2,3) (a tuple) and [1,2,3] (a list) can be used interchangeably.
When should I use one or the other, and why?
open a console and run python. Try this:
>>> list = [1, 2, 3]
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delsli
ce__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getit
em__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__r
educe__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__'
, '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__',
'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
As you may see the last on the last line list have the following methods: 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'
Now try the same for tuple:
>>> tuple = (1, 2, 3)
>>> dir(tuple)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__
format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__get
slice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__
lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__'
, '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
Only 'count' and 'index' from list methods appears here.
This is because tuples are immutable and they don't support any modifications. Instead they are simpler and faster in internal implementation.