Data Structures

  • Provides structure which can hold data together.

  • Used to store a collection of related data.

Lists

  • Holds ordered collection of items.

  • Should be enclosed in square brackets i.e. []

  • We can add, remove or even search items in a lists, implying Lists are mutable data types.

List Methods:

list.append(x) Add an item to the end of the list. Equivalent to a[len(a):] = [x].

list.extend(iterable) Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.

list.insert(i, x) Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).

list.remove(x) Remove the first item from the list whose value is equal to x. It raises a ValueError if there is no such item.

list.pop([i]) Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)

list.clear() Remove all items from the list. Equivalent to del a[:].

list.index(x[, start[, end]]) Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item. The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.

list.count(x) Return the number of times x appears in the list.

list.sort(key=None, reverse=False) Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation).

list.reverse() Reverse the elements of the list in place.

list.copy() Return a shallow copy of the list. Equivalent to a[:].

An example that uses most of the list methods:

fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
fruits.count('apple')
2
fruits.count('tangerine')
0
fruits.index('banana')
3
fruits.index('banana', 4)
6
fruits.reverse()
fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
fruits.append('grape')
fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
fruits.sort()
fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
fruits.pop()
'pear'

List as a Stack

The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack, use pop()

stack = [3, 4, 5]
stack.append(6)
stack
[3, 4, 5, 6]
stack.append(7)
stack
[3, 4, 5, 6, 7]
stack.pop()
7
stack
[3, 4, 5, 6]
stack.pop()
6
stack
[3, 4, 5]

List as Queue

It is also possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose.

To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:

from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")           # Terry arrives
queue.append("Graham")          # Graham arrives
queue.popleft()                 # The first to arrive now leaves
'Eric'
queue.popleft()                 # The second to arrive now leaves
'John'
queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

List Comprehensions

List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.

Problem: Create list of squares

Traditional approach:

squares = []
for x in range(10):
    squares.append(x**2)

squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
squares = [x**2 for x in range(10)] # More concise and readable right?
squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Few more examples:

[python for python in 'python']
['p', 'y', 't', 'h', 'o', 'n']
[number for number in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[number for number in range(10) if number % 2 == 0]
[0, 2, 4, 6, 8]
[number for number in range(100) if number % 2 == 0 if number % 5 == 0]
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
['Even' if number%2==0 else "Odd" for number in range(10)]
['Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd']
vec = [-4, -2, 0, 2, 4]
# create a new list with the values doubled
[x*2 for x in vec]
[-8, -4, 0, 4, 8]
# filter the list to exclude negative numbers
vec = [-4, -2, 0, 2, 4]
[x for x in vec if x >= 0]
[0, 2, 4]
# apply a function to all the elements
vec = [-4, -2, 0, 2, 4]
[abs(x) for x in vec]
[4, 2, 0, 2, 4]

del

a = [-1, 1, 66.25, 333, 333, 1234.5]
del a[0]
a
[1, 66.25, 333, 333, 1234.5]
del a[2:4]
a
[1, 66.25, 1234.5]
del a[:]
a
[]
del a # del can also be used to delete entire variables
a
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-32-91b8cc03fd62> in <module>
      1 del a # del can also be used to delete entire variables
----> 2 a

NameError: name 'a' is not defined

Tuples

Tuples are like lists except they are immutable like strings. They are useful when a statement or a function can safely assume that collection of values will not change.

t = 12345, 54321, 'hello!'
t[0]
12345
# Tuples may be nested:
u = t, (1, 2, 3, 4, 5)
u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
# Tuples are immutable:
t[0] = 88888
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-52-9e19cce22619> in <module>
      1 # Tuples are immutable:
----> 2 t[0] = 88888

TypeError: 'tuple' object does not support item assignment
# but they can contain mutable objects:
v = ([1, 2, 3], [3, 2, 1])
v
([1, 2, 3], [3, 2, 1])
v[0][0] = 'Changed'
v
(['Changed', 2, 3], [3, 2, 1])

Sequence Unpacking

Reverse operation of tuple packing

t = 12345, 54321, 'hello!' # Tuple packing
a, b, c = t # Sequence unpacking
print(a,b,c)

# Requres as many variables on left as ther are on right element.
12345 54321 hello!

Sets

  • Unordered collection with no duplicate elements.

  • Supports mathematical operations like union, interaction, difference.

You can create sets using {} or set() function

shopping_basket = {'apple', 'orange', 'pineapple', 'apple', 'pear'}
shopping_basket
{'apple', 'orange', 'pear', 'pineapple'}
shopping_basket = set()
type(shopping_basket)
set
shopping_basket = {}
type(shopping_basket)
dict
shopping_basket = {'apple', 'orange', 'pineapple', 'apple', 'pear'}
'apple' in shopping_basket
True
'strawberry' in shopping_basket
False
a = set('abracadabra')
b = set('alacazam')
a # unique letters in a
{'a', 'b', 'c', 'd', 'r'}
b # unique letters in b
{'a', 'c', 'l', 'm', 'z'}
a - b # letters in a but not in b
{'b', 'd', 'r'}
a | b # letters in a or b or both
{'a', 'b', 'c', 'd', 'l', 'm', 'r', 'z'}
a & b # letters in both a and b
{'a', 'c'}
a ^ b # letters in a or b but not bot
{'b', 'd', 'l', 'm', 'r', 'z'}

Set comprehensions

a = {x for x in 'abracadabra' if x not in 'abc'}
a
{'d', 'r'}

Dictionary

A dictionary is data strucuture similar to contacts. You can find an address or contact of a person by his/her/its name. In dictionary, we associate name (i.e keys) with details (i.e values) Dictionary are indexed by keys, which can be any immutable types (string or numbers) and must be unique.

contact = {
    'Ram Kasula': 9840298755,
    'Anu Pau': 98651201503,
    'Kade Hade': 9863331239,
    'Ram Kasula': 98402985,
}

contact
{'Ram Kasula': 98402985, 'Anu Pau': 98651201503, 'Kade Hade': 9863331239}
del contact['Kade Hade']
contact
{'Ram Kasula': 9840298755, 'Anu Pau': 98651201503}
contact['Santa Behen'] = 9845022233
contact
{'Ram Kasula': 9840298755, 'Anu Pau': 98651201503, 'Santa Behen': 9845022233}
list(contact)
['Ram Kasula', 'Anu Pau', 'Santa Behen']
sorted(contact)
['Anu Pau', 'Ram Kasula', 'Santa Behen']
'Santa Behen' in contact
True
'Kade Hade' in contact
False
dict([('A',1), ('B',2)])
{'A': 1, 'B': 2}

Dictionary Comprehensions

{number: number**2 for number in (1, 2, 3)}
{1: 1, 2: 4, 3: 9}

RealWorld Example

expenses = {
    'Eliza': {
        'Dahi': 280,
        'PaniPuri': 120,
        'Bara': 160,
        'Kulfi': 200,
        'Pau': 50,
    },
    'Binay': {
        'Water': 30,
    },
    'Kshitiz': {
        'Chocolate': 90,
    },
    'Sajal': {
        
    },
}

individual_expense = {person: sum(expenses[person].values()) for person in expenses.keys()}
print(individual_expense.values())
total_expense = sum(individual_expense.values())

print('Individual Expense', individual_expense)
print('Total Expense', total_expense)

for person, expense in individual_expense.items():
    print('Expense for %s is %d' % (person, ((total_expense/len(expenses)) - individual_expense[person])))
dict_values([810, 30, 90, 0])
Individual Expense {'Eliza': 810, 'Binay': 30, 'Kshitiz': 90, 'Sajal': 0}
Total Expense 930
Expense for Eliza is -577
Expense for Binay is 202
Expense for Kshitiz is 142
Expense for Sajal is 232

Practice:

  • Sum all the items in the list [1, 2, 3, 4, 5, 6, 7] without built-in methods.

  • Remove odd number from [1, 2, 3, 4, 5, 6, 7] list

  • Find the index of 4 in list [1, 2, 3, 4, 5, 6, 7]

  • Find the longest item in the list ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']

  • Concatinate 'A ' to all the items in the list ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']

  • Check if list is empty

  • Insert 7 to second last element of [1, 2, 3, 4, 5, 6, 8] list.

  • Extend ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] list with ['pineapple', 'litchi'] without append.

  • Unpack a tuple into multiple variables

  • Check if an element exist in a tuple

  • Find a repeacted item 2 in a tuple 2, 4, 5, 6, 2, 3, 4, 4, 7 Hint: use count()

  • For two set {'apple', 'orange', 'pear', 'pineapple'} and {'kiwi', 'orange', 'apple', 'guwava'}, find:

    • Intersection

    • Union

    • Difference

    • Symmetric Difference

  • Find the length of the above sets

  • For dictornary:

    contact = {
        'Ram Kasula': 9840298755,
        'Anu Pau': 98651201503,
        'Kade Hade': 9863331239,
    }
    
    • Check if Anu Pau exists ing contact

    • Concatenate below dictionary to contact:

    new_contact = {
        'Suraj Shakya': 98546625,
        'Rashmni Maharjan': 98751478556,
        'Sanjeev KC': 984656221546,
        'Ram Kasula': 9840298755,
    }
    
    • Remove Sanjeev KC from the above dict.

    • Sort the above dict by Keys

    • Check if dict is empty

    • Find common keys between above two dict.

    • Remove space from keys in above dictionary.

    • Count the number of items in the dict.

  • Using list comprehension, print a table of 2

  • Using dictionary comprehension, print a table of 5

  • Remove vowel from string A dictionary is data strucuture similar to contacts. You can find an address or contact of a person by his/her/its name

  • Calculate final amount for individual items following transaction using comprehension techniques:

    transactions = {
        'Corn Flakes': 1001/1,
        'Fruit Cake': 55.5,
        'Apple Kashmiri 1KG': 500,
        'Milk 1Packet': 40
    }
    tax_rate = 13
    
  • From above, assuming discount rate is 10%, calculate the final prices for individual items and total amount.

  • Find unique vowel from string It is a good day to Practice Python

  • Find length of each word in Today is my lucky day using dictonary comprehension

  • Find numbers which is divisible by 2 but not by 5 using list comprehension upto 100