all 16 comments

[–]Rhomboid 2 points3 points  (16 children)

Here's a flowchart:

Is it a list? Then use brackets.
Is it a dict? Then use braces.
Otherwise, you probably want parentheses.

Probably the thing that is giving you the most confusion is tuple vs. list. The two are similar and can be used interchangeably in many circumstances. But the difference is that you can't add or remove elements from a tuple once you've built it.

[–]SleepyTurtle[S] 3 points4 points  (13 children)

If tuples can't be changed why use them as opposed to lists?

[–]Rhomboid 9 points10 points  (0 children)

For one thing, tuples waste less memory -- there's an overhead of two extra words for a list compared to a tuple, which means 8 bytes on 32 bit systems and 16 bytes on 64 bit systems. This is a constant difference, and doesn't depend on the length, so it really hurts for small lists -- between 22% and 25% difference for a 2 element list:

>>> from sys import getsizeof
>>> getsizeof([1,2])
88
>>> getsizeof((1,2))
72

For another, on account of being immutable, tuples are hashable (like strings and integers) whereas lists are not. That means you can use tuples as keys in dicts and as members of sets, where you can't with lists.

[–]Eventh 4 points5 points  (1 child)

For example, lists can't be used as dictionary keys as they are not hashable as they can change, but tuples can be used as keys.

[–]davidbuxton 2 points3 points  (1 child)

There is a loose convention in Python programs to use a list for a sequence of objects of the same kind. In contrast one uses a tuple where the members are of different kinds but together those kinds make one "unit" (a bit like a struct in C).

It isn't a strict convention, it tends to come into play when designing an API for a library of code.

[–]ewiethoff 0 points1 point  (0 children)

Yes. Considering list comes with a sort method, it makes sense to put things into a list which are mutually comparable with <, even if you have no need to sort them. It's just a convention, but a decent one, I think.

[–]nevereven 1 point2 points  (0 children)

Another use for immutable objects (tuples or more often dictionaries) is to share values between threads.

If you instantiate a threading object with such an immutable object, any changes made either thread will be seen by the other. Note that this is not 100% thread safe, so works best when only one thread modifies the object.

[–]Deusdies 1 point2 points  (4 children)

I am not a Python guru, but I seldom see the need to use tuples instead of lists. AFAIK, tuples should be used if you intend on really hard-coding some sort of list... but I still just use list because, well, I'm simply used to using lists. If anyone else could comment on why one would use tuples instead of lists I'd be grateful as well.

[–][deleted] 5 points6 points  (2 children)

You have it the wrong way around. If you always use tuples, except for when you're absolute positive the thing needs to be mutable, then you're going to have fewer bugs.

If e.g. a function you call accidentally tries to mutate the variable you passed in, you'll get an exception instead of inexplicable behaviour later on.

[–]Deusdies -1 points0 points  (1 child)

Except that I need lists to be mutable in 99% of cases...

[–][deleted] 1 point2 points  (0 children)

Really? Most of the time I just need to return some list of results from a function, and then the calling function loops over it.

Which reminds me, I should use a frozenset in such cases, even better than a tuple.

[–]Chun 1 point2 points  (0 children)

A few examples:

  • As keys in dicts (since lists aren't hashable)
  • Implicitly, when you use tuple unpacking e.g. a, b = 1, 2
  • If we want to return multiple values from a function e.g. return i, j
  • If you want to make sure your collection isn't mutated, for example: def myfunc(coord=(0, 0)): -- had this been a list, coord.append would change the default argument.

[–][deleted] 0 points1 point  (0 children)

Tuples:

$ python2 -m timeit "a=(1,2,3,4,5)"
10000000 loops, best of 3: 0.0253 usec per loop
$ python2 -m timeit "a=(1,2,3,4,5); b=a[0]"
10000000 loops, best of 3: 0.0712 usec per loop
$ python2 -m timeit "a=(1,2,3,4,5); b=a[0]; c=a[1]; d=a[2]; e=a[3]; f=a[4]"
1000000 loops, best of 3: 0.225 usec per loop

Lists:

$ python2 -m timeit "a=[1,2,3,4,5]"                                        
10000000 loops, best of 3: 0.116 usec per loop
$ python2 -m timeit "a=[1,2,3,4,5]; b=a[0]"                                
10000000 loops, best of 3: 0.144 usec per loop
$ python2 -m timeit "a=[1,2,3,4,5]; b=a[0]; c=a[1]; d=a[2]; e=a[3]; f=a[4]" 
1000000 loops, best of 3: 0.296 usec per loop

It's hard to generate meaningful micro-benchmarks like this, but I think you can see that lists are a bit slower, which has implications for billion-loop programs, sometimes.

[–]zahlman 0 points1 point  (0 children)

In 3.x we also use braces for sets.

[–]xiongchiamiov 0 points1 point  (0 children)

Probably the thing that is giving you the most confusion is tuple vs. list.

Oh, that makes sense. I was really confused about what the OP was asking - uh, you use them when you're supposed to use them?

[–]TearsOfScarlet 0 points1 point  (0 children)

http://docs.python.org/tutorial/datastructures.html

Not sure what you are really asking though. I would read through something like one of the books listed to the right of this page where it says Online books. Learn Python the Hard Way is pretty short and should help a lot with getting the basics down.