5

I have ids of jail prisoners, for example. Each prisoner has a name.

I know how dictionarys work and I know how tuples work and I know how lists work, but sometimes I see a dictionary being used, and sometimes a list of tuples. Which one should I use in my case?

d = {
    1: "Mike",
    2: "Bob",
    3: "Tom"
}

vs

l = [
    (1, "Mike"),
    (2, "Bob"),
    (3, "Tom")
]

And to generalize the question: WHEN should I use a dict, and when should I use a list of tuples, what are the benefits of one?

Patrik Lippojoki
  • 1,603
  • 4
  • 19
  • 22

3 Answers3

9

You should use a list when it makes sense to store items in order. In this case it only matters that ID's are mapped to names.

A dictionary is a mapping, which means the relation between keys and values is not symmetrical. For example, it's tricky (and not always possible in the general case) to fetch a key by known value, whereas it's equally easy to filter a list (or a set, for that matter) of tuples by value of any of their items.

That being said, when choosing the data structure, it makes sense to consider how you are going to retrieve data from it. If you can see id and name as equal parts of something resembling a C struct (e.g. you'll need to search by any of them, etc.) then you're better off using a tuple or a collections.namedtuple. You can still put them in a list or a set depending on your need to keep it ordered.

But if id is a "special" field that is used to retrieve the rest of the info about the object, and it's guaranteed to be unique (well, "ID" means it), and you don't need internal order, and you want constant time random access -- of course use a dict.

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
  • If I could, I'd accept all the answers, but this one explained the usage behind different data structures, it's exactly what I wanted to know :)! – Patrik Lippojoki Jan 20 '13 at 12:19
6

There are two major differences between them:

  • Dictionaries are unordered, a list of tuples is. So if ordering matters, use the latter.

  • Mapping a key to a value takes constant time in a dict, doing the same in a list of tuples takes linear time. So, the larger your amount of key-value pairs, the more time it'll take to scan the list of tuples to find a match, while in a dictionary the lookup is near-instant, always.

    (If your tuples are kept in sorted order, you can reduce search time to O(log n) by using binary search; but that's still slower than constant time for dictionaries).

In most cases, you use a dict. Even if ordering is required, you can use a collections.OrderedDict instead to get the best of both worlds.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • To be accurate, if you keep the list sorted, you can do binary search = O(log n) time. Of course, then you lose the ordering. –  Jan 20 '13 at 11:39
  • Ah right, didn't think of the ordering! Time doesn't really matter to me that much yet, since I'm not coding anything big, but it might some day! :) I'll accept soon if no better answers are given! – Patrik Lippojoki Jan 20 '13 at 11:39
  • @delnan: but that only works if the correct order is sorted order. – Martijn Pieters Jan 20 '13 at 11:39
2

In your case, I would use a dictionary. There are several reasons you might want to consider using one.

  • The dictionary allows for usage of its API to manipulate keys and values inside it, something that would require more code to with a list of tuples.

For instance, consider this:

To get the names of the prisoners using the dictionary, you just do this:

d.values()

To do the same thing with the list of tuples you would need to do this:

names = []
for tup in l:
    names.append(tup[1])
  • The dictionary values are mutable, meaning they can be allowed to be changed. You can not do the same thing with a tuple (it is immutable).

E.g

d[1] = 'Fotis'

To achieve the same thing with a list of tuples, you would have to substitute the tuple that you want to manipulate with a new one.

E.g

l[1] = (2, 'Max')
NlightNFotis
  • 9,559
  • 5
  • 43
  • 66