Block B

Lists

Aliasing Note that we have two variables pointing at th same list.


>>> x = [1,2,3]
>>> y = x
>>> x
[1, 2, 3]
>>> y
[1, 2, 3]
>>> y[0] = 6
>>> x
[6, 2, 3]
>>> y
[6, 2, 3]

Slices of lists are lvalues. You can assign another list, tuple, or string to them.


>>> x[0]
6
>>> x[2:3]
[3]
>>> x[2:3] = ["a", "b", "c"]
>>> x
[6, 2, 'a', 'b', 'c']
>>> x[1:1] = [40,50,60]
>>> x
[6, 40, 50, 60, 2, 'a', 'b', 'c']

Here is how to splice a list in at an index.


>>> x
[6, 'c', 'a', 't', 40, 50, 60, 2, 'a', 'b', 'c']

This works as it does in strings.


>>> x[::2]
[6, 'a', 40, 60, 'a', 'c']
>>> x[1::2]
['c', 't', 50, 2, 'b']
>>> x[1::3]
['c', 40, 2, 'c']

Assignment Tricks Look at this!


>>> x = 1
>>> y = 2
>>> x,y = y,x
>>> x
2
>>> y
1

Unpack and stay a while.


>>> q = [4,5,6]
>>> x,y,z = q
>>> x
4
>>> y
5
>>> z
6

Make sure your guest list is the right size.


>>> c, d = q
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>> q
[4, 5, 6]
>>> x,y,z = q

Tuples

Tuples are like lists, but they are not mutable.


>>> t = (2,3,4)
>>> t[0] = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Watch the id here.


>>> id(t)
140524240244096
>>> t += (5,6)
>>> t
(2, 3, 4, 5, 6)
>>> id(t)
140524239982000

Notice that t is pointing at a different tuple.

By way of contrast, obseerve what happens with a list.


>>> t = [2,3,4]
>>> id(t)
140524240441728
>>> t += [5,6]
>>> id(t)
140524240441728

Slicing works the same.


>>> t = (2,3,4)
>>> id(t)
140524240244096
>>> t[1:2]
(3,)

This is verboten.


>>> t[1:2] = "cow"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Casting works in an entirely predictable manner.


>>> t
(2, 3, 4)
>>> list(t)
[2, 3, 4]
>>> tuple([5,6,7])
(5, 6, 7)
>>> tuple("cowabunga")
('c', 'o', 'w', 'a', 'b', 'u', 'n', 'g', 'a')

Like lists, tuples are a heterogeneous sequence type. They are just immutable.

Sets

Here we make an empty set.


>>> s = set()
>>> s
set()

Now we populate it.


>>> s.add("cows")
>>> s
{'cows'}
>>> print(s.add("horses"))
None
>>> s
{'horses', 'cows'}
>>> s.add("cows")
>>> s
{'horses', 'cows'}

Set is a hashed type. Sets can only contain hashable objects. To determine if something is hashable, call the built-in hash function on it.

Strings are hashable.


>>> hash("cows")
458011835615197326

Lists are not.


>>> hash([1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

But tuples are.


>>> hash((2,3,4))
-3165226637586315787

Integers will hash to themselves until they get big.


>>> hash(2)
2
>>> hash(3)
3
>>> hash(2000)
2000
>>> hash(4000)
4000
>>> hash(16000)
16000
>>> hash(32000)
32000
>>> hash(64000)
64000
>>> hash(1000000)
1000000
>>> hash(10000000)
10000000
>>> hash(100000000)
100000000
>>> hash(1000000000)
1000000000
>>> hash(10000000000)
10000000000
>>> hash(100000000000)
100000000000
>>> hash(1000000000000)
1000000000000
>>> hash(1000000000000)
1000000000000
>>> hash(10000000000000)
10000000000000


>>> type(set)
<class 'set'>
>>> s
{'horses', 'cows'}

The in operator checks for membership, just as it does for a list.


>>> "horses" in s
True

You can cast a list to a set and all duplicates will get omitted.


>>> set = set(["cow", "cow", "horse", "elephant", "ibex", "giraffe"])
>>> set
{'giraffe', 'ibex', 'elephant', 'horse', 'cow'}

I just masked the set constructor. I will unmask it.


>>> del(set)

Now let's make two sets.


>>> farm = set(["cow", "cow", "horse", "elephant", "ibex", "giraffe"])
>>> farm
{'giraffe', 'ibex', 'elephant', 'horse', 'cow'}
>>> zoo = set(["monkey", "ibex", "giraffe", "lion", "dragon of Komodo"])
>>> zoo
{'giraffe', 'ibex', 'monkey', 'lion', 'dragon of Komodo'}
>>> farm
{'giraffe', 'ibex', 'elephant', 'horse', 'cow'}

This gives all elements common to two sets.


>>> zoo.intersection(farm)
{'giraffe', 'ibex'}

This merges two sets.


>>> zoo.union(farm)
{'giraffe', 'ibex', 'elephant', 'monkey', 'lion', 'dragon of Komodo', 'horse', 'cow'}

This tells all elements residing in exactly one of two sets.


>>> farm.symmetric_difference(zoo)
{'monkey', 'elephant', 'lion', 'dragon of Komodo', 'horse', 'cow'}

Here is the subset relation.


>>> both = zoo.intersection(farm)
>>> both <= farm
True
>>> both
{'giraffe', 'ibex'}
>>> farm
{'giraffe', 'ibex', 'elephant', 'horse', 'cow'}
>>> farm <= both
False

Here is set-theoretic difference.


>>> nonfarm = zoo.difference(farm)
>>> nonfarm
{'monkey', 'dragon of Komodo', 'lion'}

This is an easy way to get rid of duplicats in a list.


>>> x =[1,1,2,3,4,4,5,7]
>>> list(set(x))
[1, 2, 3, 4, 5, 7]

Sets are unordered; you can't sort them.


>>> farm
{'giraffe', 'ibex', 'elephant', 'horse', 'cow'}
>>> farm.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'set' object has no attribute 'sort'

You can't index into them. They are not a sequence type.


>>> farm[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable

Dictionaries

Here is an empty dictionary. Dictionaries consist of key-value pairs. The keys must be hashable.


>>> d = {}
>>> type(d)
<class 'dict'>
>>> d["morrison"] = 2746
>>> d
{'morrison': 2746}
>>> d["flyboyh"] = 2742
>>> d
{'morrison': 2746, 'flyboyh': 2742}
>>> list(d.keys())
['morrison', 'flyboyh']
>>> list(d.values())
[2746, 2742]
>>>