Table of Contents

Containers

  1. Tuples.
  2. Lists.
  3. Sets.
  4. Dictionaries.
  5. Bytes.
  6. Bytearrays.
  7. Arrays.

1. Tuples

A tuples groups multiple (possiblely with different types) objects. They can be compared to (static) structures of other languages.

1.1 Tuples are (as the rest of elements of Python) objects


In [ ]:
print(type(()))

In [ ]:
help(())

1.2. Tuple definition

And some timing ... :-)


In [ ]:
!python -m timeit "x = (1, 'a', 'b', 'a')"

In [ ]:
a = (1, 'a', 'b', 'a')

1.3. Counting ocurrences in tuples


In [ ]:
a.count('a')

1.4. Searching for an item in a tuple


In [ ]:
a.index('b')

1.5. Slicing in tuples


In [ ]:
a

In [ ]:
a[2] # The 3-rd item

In [ ]:
a[2:1] # Extract the tuple from the 2-nd item to the 1-st one

In [ ]:
a[2:2] # Extract from the 2-nd item to the 2-nd item

In [ ]:
a[2:3] # Extract from the 2-nd item to the 3-rd one

In [ ]:
a[2:4] # Extract one item more

In [ ]:
a[1:] # Extract from the 1-st to the end

In [ ]:
a[:] # Extract all items (a==a[:])

1.6. Functions can return tuples


In [ ]:
def return_tuple():
    return (1, 'a', 2)
print(return_tuple())

1.7. Swapping pairs with tuples is fun!


In [ ]:
a = 1; b = 2
print(a, b)
(a, b) = (b, a)
print(a, b)

1.8. Tuples are inmutable

They can not grow:


In [ ]:
a = (1, 'a')
print(id(a),a)

In [ ]:
a += (2,) # This creates a new instance of 'a'
print(id(a),a)

... or be changed:


In [ ]:
a[1] = 2

Tuples are inmutable!


In [ ]:
a = 1; b = 2
print('"a" is in', id(a))
t = (a, b)
print('"t" is in', id(t), 'and contains', t)
a = 3
print('"a" is in', id(a))
print('"t" is in', id(t), 'and contains', t)

2. [0] Lists

A list is a data (usually dynamic) structure that holds a collection of objects, which can have different types. Internally, a list is represented as an array, therefore, lists are fast for appending and for set/pop/getting an item, and slow for removing an internal item.


In [ ]:
help([])

2.1 [1] (Of course) lists are objects


In [ ]:
print(type([]));

In [ ]:
!python -m timeit "x = [1, 'a', 'b', 'a']" # List creation is more expensive than tuple creation

(Tuples are about three times faster)


In [ ]:
a = [] # Empty list definition

2.2 [0] Appending items to a list (O(1))


In [ ]:
a.append('Hello')
a.append('world!')
a

Python lists can be "promiscuous":


In [ ]:
a.append(100)
a

2.3 [0] Inserting items (O(n))


In [ ]:
a.insert(1,'wave!')
a

2.4 [0] Deleting items from a list by content (O(n)))


In [ ]:
a.remove('Hello')
a

In [ ]:
b = ['a', 'b', 'a']; b.remove('a'); print(b)

2.4 [0] Deleting items from the begin of the list (O(1)))


In [ ]:
a.pop(0)

2.4 [0] Deleting items from the end of the list (O(1)))


In [ ]:
print(a)
a.pop(len(a)-1) # By index, equivalent to "del a[0]"
print(a)

2.5 [0] Sorting the elements of a list (O(n log n))


In [ ]:
a = []
a.append('c')
a.append('b')
a.append('a')
a

In [ ]:
a.sort()
a

In [ ]:
a.reverse()
a

In [ ]:
# Indexing
print(a[1])   # Second element
print(a[-1])  # Last element
print(a[100]) # Error

In [ ]:
a+a

In [ ]:
a*3

In [ ]:
a[::-1]

In [ ]:
x = [1,2,3,2,1] # Palindrome?
x[::-1] == x

2.6 [1] Erasing all list items (O(1))


In [ ]:
a.clear()
a

2.7 [0] List slicing (O(s))


In [ ]:
a.append('Hello')
print(a, a[0])

In [ ]:
a.append(1)
a.append(('a',2))
a.append('world!')
a

In [ ]:
print(a[1:1], a[1:2], a[1:3], a[1:], a[:], a[1:3:2])

2.8 [1] Defining lists with list comprehensions:


In [ ]:
[x**2 for x in range(10)]

In [ ]:
# http://stackoverflow.com/questions/31045518/finding-prime-numbers-using-list-comprehention
[x for x in range(2, 2000) if all(x % y != 0 for y in range(2, int(x ** 0.5) + 1))]

In [ ]:
l = [[x+y for x in range(10)] for y in range(10)]
l

In [ ]:
l[1][2]

In [ ]:
10 in l

In [ ]:
10 in l[1]

In [ ]:
# Lists of lists
x = [[1,2],[2,3,4],['a']]
x

2.9 [1] Lists are mutable objects

Lists can be modified "in-place".


In [ ]:
l = [2,3]

In [ ]:
id(l)

In [ ]:
l[1] = 4
l

In [ ]:
id(l)

3. [0] Sets

Sets are implemented as hash table of (unordered) objects, therefore sets are good for get/set/delete/searching items and bad for . Sets do not support indexing, slicing, or other sequence-like behavior.


In [ ]:
a = {1, 2, 'a', (1, 2)}
a

In [ ]:
print(type(a))

In [ ]:
help(a)

3.2. [0] Sets can grow (O(1))


In [ ]:
a.add('a')
print(a)

3.3. [0] Sets can not contain dupplicate objects


In [ ]:
a.add('a')
print(a)

3.4. [1] Sets can not contain mutable objects

Mutable objects can not be hashed :-(


In [ ]:
a = set()
a.add([1,2]) # Sets can not contain lists

In [ ]:
a = set() # Empty set
a.add({1,2,3}) # Sets can not contain sets

3.5 [0] Intersection of sets (O(min(len(s), len(t)))


In [ ]:
a = {1,2,3}
b = {2,3,4}
a.intersection(b)

3.6 [0] Union of sets (O(len(s)+len(t)))


In [ ]:
a.union(b)

3.7. [0] Sets are MUCH more efficient for searching by content than lists


In [ ]:
a = set(range(1000))
print(a)

In [ ]:
%timeit '0' in a

In [ ]:
a = list(range(1000))
print(a)

In [ ]:
%timeit '0' in a

4 [0] Dictionaries

Dictionaries are sets where each element (a key) has associated an object (a value). In fact, sets can be seen as dictionaries where the elments have not associations. As sets, dictionaries are efficient for indexing by keys.


In [ ]:
help({})

4.1 [0] Static definition of a dictionary


In [ ]:
a = {'Macinstosh':'OSX', 'PC':'Windows', 'Macintosh-Linux':'Linux', 'PC-Linux':'Linux'}
a

4.2 [0] Indexing of a dictionary by a key (O(1))


In [ ]:
a['PC']

4.3 [0] Testing if a key is the dictionary (O(1))


In [ ]:
'PC-Linux' in a

4.4 [1] Getting the keys (O(n))


In [ ]:
a.keys()

4.5 [1] Getting the values (O(n))


In [ ]:
a.values()

4.4 [1] Determining the position of a key in a dictionary (O(n))


In [ ]:
list(a.keys()).index("Macintosh-Linux")

In [ ]:
for i in a.keys():
    print(i)

4.6 [0] Inserting a new entry (O(1))


In [ ]:
a['Celullar'] = "Android"
a

[0] 4.7 Deleting an entry (O(1))


In [ ]:
del a['Celullar']
a

In [ ]:
# Modifiying an entry
a.update({"PC": "Windows 10"})
a

4.8 [1] Dictionaries are mutable


In [ ]:
id(a)

In [ ]:
a['Macintosh-Linux'] = 'Linux for the Mac'
a

In [ ]:
id(a)

4.9 [0] Looping a dictionary (O(n))


In [ ]:
for i in a:
    print(i, a[i])

In [ ]:
for i in a.values():
    print(i)

In [ ]:
for i in a.items():
    print(i)

5. Bytes

A raw bytes sequence type.

5.1. Creation of bytes sequence


In [ ]:
a = b'hello'
print(type(a))

In [ ]:
print(a)

5.2. Indexing in a bytes sequence


In [ ]:
chr(a[1])

5.3. Concatenation of bytes sequences


In [ ]:
b = b'world!'
print('"b" is in', id(b))
c = a + b' ' + b
print(c)

5.4. Bytes are inmutable


In [ ]:
a = b'abc'
print(id(a))
a += b'efg'
print(id(a))

6. Bytearray

Bytearray is a mutable implementation of an array of bytes. Therefore, appending data to a bytearray object is much faster than to a bytes object because in this last case, every append implies to create (and destroy the previous) new bytes object.


In [ ]:
%%timeit x = b''
x += b'x'

In [ ]:
%%timeit x = bytearray()
x.extend(b'x')

In [ ]:
# Array of bytes = 0
x = bytearray(10)

In [ ]:
x

In [ ]:
len(x)

In [ ]:
for i in range(len(x)):
    x[i] += 1

In [ ]:
x

In [ ]:
# A byte in Python is a 0 <= value <= 255.
x[1] = -1

In [ ]:
# A bytearray can be created from a list
x = bytearray([1,2,3])
x

In [ ]:
import sys
x = bytearray(sys.stdin.read(5).encode())
x

7. Arrays


In [ ]:
import array as arr
a = arr.array('d', [1.1, 3.5, 4.5])
print(a)

Element access


In [ ]:
a[1]

In [ ]:
a[1] = 4.0
a

Slice access


In [ ]:
a[1:2]

Appending elements


In [ ]:
a.append(5.0)
a

Concatenating arrays


In [ ]:
a.extend([5.0, 6.0, 7.0])
a

In [ ]:
a += arr.array('d', [1.1, 4.0, 4.5])
a

Deleting elements


In [ ]:
# By value
a.remove(4.0)
a

In [ ]:
# By index
a.pop(3)
a

In [ ]:


In [ ]: