Python Lists v. Dictionaries

Varun Srinivasan
The Startup
Published in
5 min readMay 23, 2020
Photo credit — https://flic.kr/p/vChvzh

Lists and Dictionaries are the most commonly used data structures in Python. They are mutable — which means they can be modified in the course of the program without changing its identity. Before we jump into our discussion on the topic, let’s understand why Lists and Dictionaries are mutable.

Mutability

An object is said to be mutable as the identity of the object is not changed in the lifetime of the program based on its scope. This is one of the main reasons why we should consider using Lists and Dictionaries more in our day-to-day coding. Let me convince you why.

Let’s consider an integer object x initialized and assigned a value. When we modify the value of x with x + 5, the id of the object x changes — within the same program.

>>> x = 6
>>> id(x)
4324708656
>>>
>>> x = x + 5
>>> id(x)
4324708816

When we do the same thing to a value in a list, the id remains the same.

>>> x = [1,4,8]
>>> id(x)
4473765960
>>> x[0] += 5
>>> x
[6, 4, 8]
>>> id(x)
4473765960

The above experiment shows that immutable objects create a new copy every time you modify its value. So, the next time you append a word or a character to a string, you will know that for every addition/deletion you make, you leave the old value hanging in the memory (which will be cleaned up by the Python garbage collector later on) while creating a new string object with the new value. A better way to optimize string concatenations is to use a list and join the elements as follows.

def inefficientStringConcat() -> str:
x = ''
print(id(x))
for i in range(1, 6):
# Appending each value of i to the string
x += str(i)
print(id(x))
return x
def efficientStringConcat() -> str:
x = []
print(id(x))
for i in range(1, 6):
# Appending each value of i to the list
x.append(str(i))
print(id(x))
return ''.join(x)

Side note — Visualize an object’s id as a database unique id for a record in a table. The id should not to be confused with the memory pointer. Unlike C/C++, Python doesn’t expose any object’s memory pointer for security.

Still not convinced? 😃

Initializing and manipulating Lists and Dictionaries

We discussed the similarity between the two popular data structures above. Now, let’s discuss its differences. Lists are ordered — that means, we get to refer to a value by its index baselining the index to 0; just like saying you want the 5th book from the left to a book vendor. Lists are typically arrays with an exception that the elements in a Python list need not be of the same datatype. On the other hand, dictionaries are unordered but has a unique id to store each value; just like referring to an order number to retrieve your order details and shipment progress. Dictionaries are counterparts to Hash maps as referred in other programming languages.

x = list()
y = [100, 'Sydney', 4.95]
# Yes, you saw that right. Python allows a heterogenous list that contains elements of different datatypes.
a = dict()
b = {'happy': '😊', 'sad': '🙁', 'evil': '😈'}
# Yup. Unicode characters are allowed too.

You can also embed a dictionary into a list or a list into a dictionary.

m = [1, 2, {'python': 'cool'}]
n = {'version': [1,2,3], 'book_name': 'Python for dummies'}

Some useful methods for each of the data structure is listed below:

+-----------+-------------------------+------------------+
| Operation | List | Dictionary |
+-----------+-------------------------+------------------+
| Insert | x.insert(index, value) | a['key']= value |
| | x.append(value) | |
| Update | x[index] = new_value | a['key']= nValue |
| Remove | x.pop(index) | a.pop(key) |
| | x.remove(value) | del(a['key']) |
+-----------+-------------------------+------------------+

There are other useful methods for list operations such as:

  • a.clear() to remove all items from the list. Alternate to it is del a[:]
  • a.index() to search for an item in the list.
  • a.count() to find the number of occurrences of an item.
  • a.reverse() to reverse the elements. a[::-1] also does the trick.

Similarly, there are some useful methods for dictionary operations as well. Some of them are,

  • b.clear()to remove all items from the dictionary.
  • b.get(key) to get the value of a key.
  • b.items() to iterate through the dictionary. for i in d: i holds the key, and we use d[i] in the loop to access the value corresponding to the key i. Instead for key, value in d.items(): gets us keys and values in the iteration.

Side node — There are ways to convert a dictionary into a list data structure and vice versa. Also, there are ordered dictionaries which is out of scope of this article, but I will put together another one to elaborate on the same.

Slicing and copying

Slicing is only applicable for lists. The : delimiter does it all.

  • You can use it to refer to a range of values in a list like a[5:9] which returns a list containing the elements in the fifth, sixth, seventh and eighth indices from a list.
  • If the end boundary is not defined like a[5:], we will be returned a list of all the elements from the fifth index to the end of a list.
  • You can also say that you want all the elements excluding the last element of the list by a[:-1].
  • You can get more fancy by excluding the first two and last two elements of a list by a[-2:-2].
  • You can skip elements by giving a third parameter like a[1:6:2] which returns a list of elements in the first, third, fifth indices skipping second and forth elements of a list.

Copying data structures in python is orthogonal to assignment. For a list,

a = [1, 4, 8, 16, 32]
bb = a
# id(a) and id(bb) are the same. Which means, if list a is changed, it reflects on list bb.
# To shallow copy, use the copy method or slice
b = a.copy()
c = a[:]
# To deep copy,
d = a.deepcopy()

For a dictionary,

a = {'python': 'cool', 'java':'fast', 'go': 'both'}
bb = a
# creates a reference to object a. Changes made to object a will # reflect on object bb
# To copy, use the copy method or the unpacking operator **
b = a.copy()
c = {**a}

Side note — Shallow copy is only copying the reference of the embedded object when the list has an object reference embedded in it. On the contrary, deep copy is to copy the contents of the referenced object over to the new copied object.

I’d like to keep sorting to another article as it is an other essential and powerful tool that comes very handy. I’ve also not covered tuples and sets which are sisters of the list data structure with its unique features. Until I meet you through my next article, happy coding! 🧑‍💻

--

--

Varun Srinivasan
The Startup

Backend Web Developer and AI enthusiast. An avid learner.