Python Language Intro (Part 3)

Agenda

  1. Language overview
  2. White space sensitivity
  3. Basic Types and Operations
  4. Statements & Control Structures
  5. Functions
  6. OOP (Classes, Methods, etc.)
  7. Immutable Sequence Types (Strings, Ranges, Tuples)
  8. Mutable data structures: Lists, Sets, Dictionaries
In [3]:
# by default, only the result of the last expression in a cell is displayed after evaluation.
# the following forces display of *all* self-standing expressions in a cell.

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

7. Immutable Sequence Types: Strings, Ranges, Tuples

Recall: All immutable sequences support the common sequence operations. For many sequence types, there are constructors that allow us to create them from other sequence types.

Strings

In [2]:
'hello'[1]
Out[2]:
'e'
In [3]:
'hello'[1]='A'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-a6518b465dd3> in <module>()
----> 1 'hello'[1]='A'

TypeError: 'str' object does not support item assignment

Ranges

In [5]:
list(range(10))
Out[5]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [7]:
list(range(10, 20))
Out[7]:
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
In [8]:
list(range(20, 50, 5))
Out[8]:
[20, 25, 30, 35, 40, 45]
In [9]:
list(range(10, 0, -1))
Out[9]:
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
In [12]:
len(range(10))
11 in range(10)
range(3)+ range(5)
Out[12]:
10
Out[12]:
False
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-ad7cfb204c7b> in <module>()
      1 len(range(10))
      2 11 in range(10)
----> 3 range(3)+ range(5)

TypeError: unsupported operand type(s) for +: 'range' and 'range'

Tuples

In [13]:
()
Out[13]:
()
In [19]:
(1, 2, 3)
(1,2,3)[2]
#(1,2,3)[0]=5
(1,2,3)[3]
Out[19]:
(1, 2, 3)
Out[19]:
3
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-19-a1d14274785c> in <module>()
      2 (1,2,3)[2]
      3 #(1,2,3)[0]=5
----> 4 (1,2,3)[3]

IndexError: tuple index out of range
In [23]:
a=('a', 10, False, 'hello')
a[3]
a[3][0]
len(a)
Out[23]:
'hello'
Out[23]:
'h'
Out[23]:
4
In [20]:
tuple(range(10))
Out[20]:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
In [21]:
tuple('hello')
Out[21]:
('h', 'e', 'l', 'l', 'o')

8. Mutable data structures: Lists, Sets, Dicts

Lists

This list supports the mutable sequence operations in addition to the common sequence operations.

In [4]:
l=[1,'a',(1,2,3)]
m=l.copy()
l
m
m[0]=2
l
m
m[1]='b'
l
m
m[2]=5
l
m
Out[4]:
[1, 'a', (1, 2, 3)]
Out[4]:
[1, 'a', (1, 2, 3)]
Out[4]:
[1, 'a', (1, 2, 3)]
Out[4]:
[2, 'a', (1, 2, 3)]
Out[4]:
[1, 'a', (1, 2, 3)]
Out[4]:
[2, 'b', (1, 2, 3)]
Out[4]:
[1, 'a', (1, 2, 3)]
Out[4]:
[2, 'b', 5]
In [3]:
#shallow copy demonstrated on list of lists
l = [[1, 2], [3, 4]]
m = l.copy()
m
l
l[1][0] = 5  #changes both l and m
m
l
Out[3]:
[[1, 2], [3, 4]]
Out[3]:
[[1, 2], [3, 4]]
Out[3]:
[[1, 2], [5, 4]]
Out[3]:
[[1, 2], [5, 4]]
In [29]:
l = [1, 2, 1, 1, 2, 3, 3, 1]
In [30]:
len(l)
Out[30]:
8
In [31]:
l[5]
Out[31]:
3
In [32]:
l[1:-1]
Out[32]:
[2, 1, 1, 2, 3, 3]
In [33]:
l + ['hello', 'world']
Out[33]:
[1, 2, 1, 1, 2, 3, 3, 1, 'hello', 'world']
In [34]:
l # `+` does *not* mutate the list!
Out[34]:
[1, 2, 1, 1, 2, 3, 3, 1]
In [35]:
l * 3
Out[35]:
[1, 2, 1, 1, 2, 3, 3, 1, 1, 2, 1, 1, 2, 3, 3, 1, 1, 2, 1, 1, 2, 3, 3, 1]
In [36]:
sum = 0
for x in l:
    sum += x
sum
Out[36]:
14

Mutable list operations

In [37]:
l = list('hell')
In [38]:
l.append('o')
In [39]:
l
Out[39]:
['h', 'e', 'l', 'l', 'o']
In [40]:
l.append(' there')
In [42]:
l
Out[42]:
['h', 'e', 'l', 'l', 'o', ' there']
In [46]:
l.append(list((3,4)))
l
Out[46]:
['h', 'e', 'l', 'l', 'o', ' there', (3, 4), [3, 4]]
In [48]:
del l[-1]
l
Out[48]:
['h', 'e', 'l', 'l', 'o', ' there']
In [ ]:
l.extend(' there')
In [ ]:
l
In [ ]:
l[2:7]
In [ ]:
del l[2:7]
In [ ]:
l
In [ ]:
l[]
In [50]:
words=['cat', 'dog','bird','ferret']
for w in words[:]:    #  oppy of words on the fly
    if len(w)>3:
        words.insert(0,w)
words
Out[50]:
['ferret', 'bird', 'cat', 'dog', 'bird', 'ferret']

List comprehensions

In [51]:
[x for x in range(10)]
Out[51]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [52]:
[2*x+1 for x in range(10)] # odd numbers
Out[52]:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
In [53]:
[2*x+1 for x in range(10) if x>5] # odd numbers
Out[53]:
[13, 15, 17, 19]
In [55]:
[(x,2*x+1) for x in range(10) if x>5] # odd numbers
Out[55]:
[(6, 13), (7, 15), (8, 17), (9, 19)]
In [58]:
# What circles of radius 1 to 5 have more area than squares with sides 1 to 5?
import math
[radius     for radius in range(1,6)    if  math.pi*radius/2*radius/2 > radius*radius  ]
Out[58]:
[]
In [59]:
adjs = ('hot', 'blue', 'quick')
nouns = ('table', 'fox', 'sky')
phrases = []
for adj in adjs:
    for noun in nouns:
        phrases.append(adj + ' ' + noun)
In [60]:
phrases
Out[60]:
['hot table',
 'hot fox',
 'hot sky',
 'blue table',
 'blue fox',
 'blue sky',
 'quick table',
 'quick fox',
 'quick sky']
In [61]:
[adj + ' ' + noun for adj in adjs for noun in nouns]
Out[61]:
['hot table',
 'hot fox',
 'hot sky',
 'blue table',
 'blue fox',
 'blue sky',
 'quick table',
 'quick fox',
 'quick sky']
In [4]:
import random
flips=''
for i in range(100):
    flips=flips+str(random.randint(0,1))
flips
Out[4]:
'1111111111000011010011000111010111001101010010010001101000110111101110011110010000100001100111101111'
In [5]:
flips.index('0110')
Out[5]:
13
In [6]:
key='00'
if flips[0:len(key)]==key:
    print(0)
else:
    if key[0]=='0':
        newKey='1'+key+'1'
    else:
        newKey='0'+key+'0'
    print(flips.index(newKey))
17
In [3]:
# improvement converting the flips list into a runs list
runs=[]
prev=flips[0]
runCount=1
for c in flips[1:]:
    if c==prev:
        runCount+=1
    else:
        if prev=='0':
            runs.append(runCount)
        else:
            runs.append(-1*runCount)
        runCount=1
        prev=c
str(runs)
Out[3]:
'[2, -1, 2, -3, 1, -1, 1, -1, 1, -3, 2, -1, 2, -1, 1, -1, 1, -1, 1, -1, 1, -3, 3, -3, 1, -6, 4, -1, 1, -3, 3, -1, 1, -2, 4, -4, 1, -2, 2, -1, 1, -1, 2, -6, 3, -3, 6, -1]'
In [7]:
# process the runs list
key='11'
if key[0]=='0':
    target=len(key)
else:
    target=-1*len(key)
sum=0
runs.index(target)
for n in runs[0:runs.index(target)]:
    sum+=abs(n)
sum
Out[7]:
59

Sets

A set is a data structure that represents an unordered collection of unique objects (like the mathematical set).

In [1]:
s = {1, 2, 1, 1, 2, 3, 3, 1}
In [2]:
s
Out[2]:
{1, 2, 3}
In [5]:
t = {2, 3, 4, 5}
In [6]:
s.union(t)
Out[6]:
{1, 2, 3, 4, 5}
In [7]:
s.difference(t)
Out[7]:
{1}
In [8]:
s.intersection(t)
Out[8]:
{2, 3}

Dictionaries (AKA Maps or HashTables)

A dictionary is a data structure that contains a set of unique key → value mappings.

In [9]:
d = {
    'Superman':  'Clark Kent',
    'Batman':    'Bruce Wayne',
    'Spiderman': 'Peter Parker',
    'Ironman':   'Tony Stark'
}
In [10]:
d['Ironman']
Out[10]:
'Tony Stark'
In [11]:
d['Ironman'] = 'James Rhodes'
In [12]:
d
Out[12]:
{'Batman': 'Bruce Wayne',
 'Ironman': 'James Rhodes',
 'Spiderman': 'Peter Parker',
 'Superman': 'Clark Kent'}

Dictionary comprehensions

In [13]:
{e:2**e for e in range(0,100,10)}
Out[13]:
{0: 1,
 10: 1024,
 20: 1048576,
 30: 1073741824,
 40: 1099511627776,
 50: 1125899906842624,
 60: 1152921504606846976,
 70: 1180591620717411303424,
 80: 1208925819614629174706176,
 90: 1237940039285380274899124224}
In [14]:
{x:y for x in range(3) for y in range(10)}
Out[14]:
{0: 9, 1: 9, 2: 9}
In [17]:
sentence = 'a man a plan a canal panama'
palindrone={w:w[::-1] for w in sentence.split()}
palindrone
Out[17]:
{'a': 'a', 'canal': 'lanac', 'man': 'nam', 'panama': 'amanap', 'plan': 'nalp'}
In [18]:
for i in palindrone:
    print (i)
a
man
plan
canal
panama
In [19]:
for i in palindrone.values():
    print (i)
a
nam
nalp
lanac
amanap
In [28]:
palindrone['Matt']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-28-2ecb554e15d9> in <module>()
----> 1 palindrone['Matt']

KeyError: 'Matt'
In [31]:
palindrone.get('Matt')
palindrone.get('canal')
Out[31]:
'lanac'
In [ ]:
for i,j in palindrone.items():
    print (i+" "+j)

Demo

In [21]:
import urllib.request     
peter_pan_text = urllib.request.urlopen('https://www.gutenberg.org/files/16/16-0.txt').read().decode() 
In [22]:
peter_pan_text[0:100]
Out[22]:
'\ufeffThe Project Gutenberg EBook of Peter Pan, by James M. Barrie\r\n\r\nThis eBook is for the use of anyone'
In [23]:
peter_pan_words=peter_pan_text.split()
In [24]:
peter_pan_words[0:20]
Out[24]:
['\ufeffThe',
 'Project',
 'Gutenberg',
 'EBook',
 'of',
 'Peter',
 'Pan,',
 'by',
 'James',
 'M.',
 'Barrie',
 'This',
 'eBook',
 'is',
 'for',
 'the',
 'use',
 'of',
 'anyone',
 'anywhere']
In [26]:
'Peter1' in peter_pan_words
Out[26]:
False
In [36]:
peter_pan_words.count('Hook')
len(peter_pan_words)
Out[36]:
84
Out[36]:
50765
In [35]:
peter_pan_word_count={}
for w in peter_pan_words:
    if w in peter_pan_word_count:
        peter_pan_word_count[w]+=1
    else:
        peter_pan_word_count[w]=1   # add a new word to dict
peter_pan_word_count['the']   
len(peter_pan_word_count)
Out[35]:
2331
Out[35]:
9334
In [38]:
max(peter_pan_word_count)
Out[38]:
'\ufeffThe'
In [39]:
max(peter_pan_word_count.values())
Out[39]:
2331
In [41]:
a=[4,2,6,8,9,2]
sorted(a)
Out[41]:
[2, 2, 4, 6, 8, 9]
In [42]:
p=sorted(peter_pan_word_count)
p[0:10]
Out[42]:
['#10000,',
 '#16]',
 '$5,000)',
 "'AS-IS,'",
 "'Ay,",
 "'Boy,",
 "'Down",
 "'How",
 "'I",
 "'I'm"]
In [44]:
p=sorted(peter_pan_word_count.values(),reverse=True)
p[0:10]
Out[44]:
[2331, 1396, 1214, 962, 929, 898, 866, 683, 564, 498]
In [46]:
x=["cat", "dog","mouse", "ant"]
sorted(x)
Out[46]:
['ant', 'cat', 'dog', 'mouse']
In [47]:
sorted(x,key=len)
Out[47]:
['cat', 'dog', 'ant', 'mouse']
In [50]:
p=sorted(peter_pan_word_count.items(),key=lambda x:x[1],reverse=True)
p[0:10]
Out[50]:
[('the', 2331),
 ('and', 1396),
 ('to', 1214),
 ('a', 962),
 ('of', 929),
 ('was', 898),
 ('he', 866),
 ('in', 683),
 ('that', 564),
 ('had', 498)]