Python — List vs Tuple vs Dictionary
By: Rohan Paul
Tags: Python, Programming

Dictionary

A dictionary is a key:value pair, similar to an associative array found in other programming languages. A dictionary is like an address-book where you can find the address or contact details of a person by knowing only his/her name i.e. we associate keys (name) with values (details). Note that the key must be unique just like you cannot find out the correct information if you have two persons with the exact same name.

Iterating a Dictionary

The Python dictionary allows the programmer to iterate over its keys using a simple for loop. Let’s take a look:

my_dict = {1: 'one', 2: 'two', 3: 'three'}

for key in my_dict:

print(key) Output

1

2

3

Python 3 changed things up a bit when it comes to dictionaries. In Python 2, you could call the dictionary’s keys() and values() methods to return Python lists of keys and values respectively:

But in Python 3, you will get views returned:

# Python 3 my_dict = {1: 'one', 2: 'two', 3: 'three'} my_dict.keys() # dict_keys([1, 2, 3]) my_dict.values() # dict_values(['one', 'two', 'three']) # my_dict.items() dict_items([(1, 'one'), (2, 'two'), (3, 'three')])

A view object has some similarities to the range object we saw earlier — it is a lazy promise, to deliver its elements when they’re needed by the rest of the program. We can iterate over the view, or turn the view into a list like this:

my_dict = {1: 'one', 2: 'two', 3: 'three'} print(list(my_dict.keys())) #[1, 2, 3]

The values method is similar; it returns a view object which can be turned into a list:

my_dict = {1: 'one', 2: 'two', 3: 'three'} print(list(my_dict.values())) # ['one', 'two', 'three']

Alternatively, to get list of keys as an array from dict in Python 3, You can use * operator to unpack dict_values:

my_dict = {1: 'one', 2: 'two', 3: 'three'} print([*my_dict.keys()]) # [1, 2, 3] my_dict = {1: 'one', 2: 'two', 3: 'three'} print([*my_dict.values()]) # ['one', 'two', 'three']

The items method also returns a view, which promises a list of tuples — one tuple for each key:value pair:

Restrictions on Dictionary Keys

Almost any type of value can be used as a dictionary key in Python, e.g. integer, float, and Boolean objects. However, there are a couple restrictions that dictionary keys must abide by.

First, a given key can appear in a dictionary only once. Duplicate keys are not allowed.

Secondly, a dictionary key must be of a type that is immutable. A tuple can also be a dictionary key, because tuples are immutable:

d = {(1, 1): 'a', (1, 2): 'b', (2, 1): 'c', (2, 2): 'd'}

d[(1,1)]

'a'

d[(2,1)]

'c'

However, neither a list nor another dictionary can serve as a dictionary key, because lists and dictionaries are mutable:

Restrictions on Dictionary Values

By contrast, there are no restrictions on dictionary values. Literally none at all. A dictionary value can be any type of object Python supports, including mutable types like lists and dictionaries, and user-defined objects, which you will learn about in upcoming tutorials.

There is also no restriction against a particular value appearing in a dictionary multiple times:

To check if a key exists in a Python dictionary

there is often a need to extract the value of a given key from a dictionary; however, it is not always guaranteed that a specific key exists in the dictionary.

When you index a dictionary with a key that does not exist, it will throw an error.

Hence, it is a safe practice to check whether or not the key exists in the dictionary prior to extracting the value of that key. For that purpose, Python offers two built-in functions:

has_key()

if - in statement

However the has_key method has been removed from Python3.

The code snippet below illustrates the usage of the if - in statement to check for the existence of a key in a dictionary:

Stocks = {'a': "Apple", 'b':"Microsoft", 'c':"Google"} key_to_lookup = 'a' if key_to_lookup in Stocks: print "Key exists" else: print "Key does not exist"

So, how does Python find out whether the value is or is not in the dictionary without looping through the dictionary somehow?

Becuase, dictionaries in Python are implemented as hash tables under the hood, which allow you to look up whether an item exists in the table directly in constant run time instead of having to go through every element one at a time to check membership like you would with a normal list or array. Basically, the keys or index values for a dictionary are passed through a complicated “hash function” which assigns them to unique buckets in memory. A given input value for the key or index will always access the same bucket when passed through the hash function, so instead of having to check every value to determine membership, you only have to pass the index through the hash function and then check if anything exists at the bucket associated with it. The drawback of dictionaries is that they are not ordered and require more memory than lists.

Aliasing and copying of Dictionaries

Because dictionaries are mutable, we need to be aware of aliasing. Whenever two variables refer to the same object, changes to one affect the other.

If we want to modify a dictionary and keep a copy of the original, use the copy method. For example, in the below original_dict is a dictionary that contains pairs of original_dict:

original_dict = {"up": "down", "right": "wrong", "yes": "no"}

alias = original_dict

copy = original_dict.copy() # Shallow copy

alias and original_dict refer to the same object; copy refers to a fresh copy

of the same dictionary. If we modify alias, original_dict is also changed:

alias["right"] = "left"

original_dict["right"] # Will output 'left'

If we modify copy, original_dict is unchanged:

copy["right"] = "privilege"

original_dict["right"] # Will output 'left'

Merging dictionaries

Say you have two dicts and you want to merge them into a new dict without altering the original dicts:

x = {'a': 1, 'b': 2}

y = {'b': 3, 'c': 4}

The desired result is to get a new dictionary ( z ) with the values merged, and the second dict's values overwriting those from the first.

z

{'a': 1, 'b': 3, 'c': 4}

For dictionaries in Python, x and y, z becomes a shallowly merged dictionary with values from y replacing those from x.

In Python 3.5 or greater: z = {**x, **y} #In Python 2, (or 3.4 or lower) we have to write a function that will take two dictionary as its argument. def merge_two_dicts(x, y):

z = x.copy() # start with x’s keys and values

z.update(y) # modifies z with y’s keys and values & returns None

return z #and now: z = merge_two_dicts(x, y)

Some implementational differences between Lists and Dictionary

While Copying — Lists vs Dictionary

Mutable objects come with one potentially prominent drawback: changes made to an object are visible from every reference to that object. All mutable objects work this way because of how Python references objects, but that behavior isn’t always the most useful. In particular, when working with objects passed in as arguments to a function, the code that called the function will often expect the object to be left unchanged. If the function needs to make modifications in the course of its work, i.e. if we want to make changes to an object without those changes showing up elsewhere, we’ll need to copy the object first.

Lists, support slicing to retrieve items from the list into a new list. That behavior can be used to get all the items at once, creating a new list with those same items. Simply leave out the start and end values while slicing, and the slice will copy the list automatically:

a = [1, 2, 3] b = a[:] print(b) # Output

[1, 2, 3]

# The : operator here, as we know, works as a slice operator with sequence

We could also use list.copy() to make a copy of the list.

The slice() method above returns a slice object, however, ror dictionaries, by contrast, slice objects aren’t hashable, so dictionaries don’t allow them to be used as keys.