Home

Title

Table of Contents

title---- title

Intro to Python Collections

Appending and adding to lists.

### a_list=[1,2,3] ### a_list a_list.append([4,5]) # [1,2,3,[4,5]] our_list = list(range(10)) ### our_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ### our_list + [10,11,12] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ### our_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ### our_list=our_list+[10,11,12] ### our_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

For splitting strings themselves we can use str.split(str="", num=string.count(str))

Extending Collections

Normally cleaner for larger lists than the + symbol.

>>> our_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] >>> our_list.extend(range(13, 20)) >>> our_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

How do add new items inside the list?

>>> alpha= list('acdf') >>> alpha ['a', 'c', 'd', 'f'] >>> alpha.insert(1,'b') >>> alpha ['a', 'b', 'c', 'd', 'f'] >>> alpha.insert(4,'e') >>> alpha ['a', 'b', 'c', 'd', 'e', 'f']

Shopping List

# note - you should use enumerate once you get there >>> def show_help(): print("\nDoing a print_") >>> def show_list(): count=1 for item in shopping_list: print("{}: {}".format(count, item)) count+=1

Other helpful use cases...

while True: #do stuff new_stuff = input("> ") if new_stuff == "DONE": print('Done') break elif #do other stuff break else ...

Removing Items from a List

a_list=list('abzde') a_list.index('z') del a_list[2] a_string = "Hello" # this will delete the string - although the del can't be used to delete within the string # strings themselves are immutable del a_string # remove for the list my_list = [1,2,3,1] # remove ONLY removes the first instance from the list my_list.remove(1) my_list # [2,3,1]

Removing vowels from a list of words and capitalising them

names = ["Dennis", "Billy", "Trojan", "Horse"] vowels = list('aeiou') output = [] for name in names: name_list = list(name.lower()) for vowel in vowels: while True: try: state_list.remove(vowel) except: break output.append(''.join(name_list).capitalize()) print(output)

Pop an item from the list

pop() removes an item by index but gives us the item.

names = ["Dennis", "Billy", "Trojan", "Horse"] first = names.pop() // gives the first name another = names.pop(2) // gives index 3

// Quiz Challenge // 1. Move the '1' to the front of the list the_list = ["a", 2, 3, 1, False, [1, 2, 3]] # Your code goes below here the_list.insert(0, the_list.pop(3))


Slices

Slices mean we can get back more than one item from a list. We call this slicing.

Something important to not is the useability of have the [:] call for a copy of the list!

my_string="Hello there!" my_string[0:5] my_list=list(range(1,6)) my_list[0:2] // same as my_list[:2] my_list[2:len(my_list)] my_list[1:] my_list[:] // gets back a copy of the list my_new_list = [4,2,1,3,5] my_new_list.sort() my_new_list

Slicing with a Step

How can we slice that move backward or that skip items?

my_list=list(range(20)) # let's get the even numbers my_list[::2] "Testing"[::2] # reversing "Slap"[::-1] # getting the middle slice - must swap positions! my_list[8:2:-1] # negative indexes will also give you the positions from the end my_list[-1] # example of grabbing the first four iterables through a Python function def first_4(iter): return iter[:4]

Deleting or Replacing Slices

We can delete and replace with lists.

my_list = [1,2, 'a', 'b', 5,6,'f','g'] # what if I just want letters? my_list[4:7] = ['e','f']

Code Challenge

def sillycase(c): return c[:round(len(c) / 2)].lower() + c[round(len(c) / 2):].upper()


Dictionaries

Key-Value organisation. They themselves do not have an order.

my_dict = {'name': 'Dennis', 'job': 'Software Engineer'} # to access it, you need to use the key name my_dict['name']

Dictionaries can contain anything - even your own custom classes.

named_dict = { 'name' : { 'first' : 'Dennis', 'last': 'OKeeffe'} } named_dict['name']['first'] # tuple game dict game_dict = {(1,2) : True} game_dict[(1,2)]

Challenge: Check if a dict key is in the list

def members(dict, keys): counter = 0 for key in dict: if key in keys: counter = counter + 1 return counter

Managing Keys

We can del keys etc similar to the way we do it for keys.

>>> my_dict['test'] = 'value' >>> my_dict {'test': 'value', 'job': 'Software Engineer', 'name': 'Dennis'} >>> del my_dict['test'] >>> my_dict {'job': 'Software Engineer', 'name': 'Dennis'} # we can use update for multiple keys etc >>> my_dict.update({'job': 'Developer', 'age': 24, 'state': 'New South Wales'}) >>> my_dict {'job': 'Developer', 'name': 'Dennis', 'age': 24, 'state': 'New South Wales'}

Challenge: Create a function named word_count() that takes a string. Return a dictionary with each word in the string as the key and the number of times it appears as the value.

def word_count(sentence): new_dict = {} word_list = sentence.split() count = 0 for original_word in word_list: if original_word not in new_dict: count = 0 for comparison_word in word_list: if original_word == comparison_word: count += 1 new_dict.update({original_word: count}) return new_dict

Unpacking Dictionaries

You can give placeholders a name and use dictionaries to make it a little easier.

>>> my_string = "Hi my name is {name} and I live in {state}" >>> my_string 'Hi my name is {name} and I live in {state}' >>> my_string.format('Dennis', 'Sydney') Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'name' >>> my_string.format('name'='Dennis', state='Sydney') File "<stdin>", line 1 SyntaxError: keyword can't be an expression >>> my_string.format(name='Dennis', state='Sydney') 'Hi my name is Dennis and I live in Sydney' # how do we make this programmatic? >>> test_dict = {'name':'Dennis', 'state':'Sydney'} >>> my_string.format(**test_dict) 'Hi my name is Dennis and I live in Sydney'

Code Challenge: Create a function named string_factory that accepts a list of dictionaries and a string. Return a new list built by using .format() on the string, filled in by each of the dictionaries in the list.

dicts = [ {'name': 'Michelangelo', 'food': 'PIZZA'}, {'name': 'Garfield', 'food': 'lasanga'}, {'name': 'Walter', 'food': 'pancakes'}, {'name': 'Galactus', 'food': 'worlds'} ] string = "Hi, I'm {name} and I love to eat {food}!" def string_factory(list_of_dict, str): new_list = [] for ind_list in list_of_dict: new_list.append(str.format(**ind_list)) return new_list

Dictionary Iteration

Again, Dictionaries in Python do not have a set order, but we can still iterate over them.

>>> my_dict {'job': 'Developer', 'name': 'Dennis', 'age': 24, 'state': 'New South Wales'} >>> for thing in my_dict: ... print(thing) ... job name age state >>> for key in my_dict: ... print(my_dict[key]) ... Developer Dennis 24 New South Wales >>> for value in my_dict.values(): ... print(value) ... Developer Dennis 24 New South Wales

Create a function named most-classes that takes a dictionary of teachers. Each key is a teacher's name and their value is a list of classes they've taught. most-classes should return the teacher with the most classes.

Next, create a function named num_teachers that takes the same dictionary of teachers and classes. Return the total number of teachers.

Now, create a function named stats that takes the teacher dictionary. Return a list of lists in the format [<teacher name>, <number of classes>]. For example, one item in the list would be ['Dave McFarland', 1].

Great work! Finally, write a function named courses that takes the teachers dictionary. It should return a single list of all of the courses offered by all of the teachers.

def most_classes(teachers): highest_value = 0 teacher_name = "" for teacher in teachers: if len(teachers[teacher]) > highest_value: highest_value = len(teachers[teacher]) teacher_name = teacher return teacher_name def num_teachers(teachers): return len(teachers) def stats(teachers): return_list = [] for teacher in teachers: return_list.append([teacher, len(teachers[teacher])]) return return_list def courses(teachers): single_courses = [] for courses in teachers.values(): for course in courses: if course not in single_courses: single_courses.append(course) return single_courses


Tuples

Lists themselves can be mutated, but sometimes we want the collections to stay the same. That's where tuples come in. They themselves are immutable.

Tuples do not support item assignment.

>>> tupleTest = (1,2,3) >>> tupleTest (1, 2, 3) >>> my_second_tuple = 1,2,3 >>> my_second_tuple (1, 2, 3) >>> my_third_tuple = tuple([1,2,3]) >>> my_third_tuple (1, 2, 3) >>> dir(tuple) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']

Tuple Packing and Unpacking

Here we create a tuple that has valued assigned by another tuple. It's referred to as simulatneous assignment.

>>> a,b = 1,2 >>> a 1 >>> b 2 # unpacking >>> c = (3,4) >>> (d,e) = c >>> d 3 >>> e 4 # packing >>> f = d,e >>> f (3, 4) >>> f == c True # swapping the value >>> del a >>> del b >>> a = 1 >>> b = 2 >>> a,b = b,a >>> a 2 >>> b 1 # function example >>> def my_func(): ... return 1,2,3 ... >>> my_func() (1, 2, 3) >>> a,b,c = my_func() >>> a 1 >>> b 2 >>> c 3

Challenge: Create a function named stringcases that takes a string and returns a tuple of four versions of the string: uppercased, lowercased, titlecased (where every word's first letter is capitalized), and a reversed version of the string.

def stringcases(str): uppercased = str.upper() lowercased = str.lower() titlecased = str.title() reverse = str[::-1] return uppercased, lowercased, titlecased, reverse

Tuples with functions

We can use enumerate for some packing etc.

>>> alpha = list('abcdefghijklmnopqrstuvwxyz') >>> alpha ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] >>> dir(enumerate) ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'next'] # prints the help >>> help(enumerate) >>> for (index, letter) in enumerate(alpha): ... print('{}: {}').format(index,letter) ... 0: a 1: b 2: c 3: d 4: e 5: f 6: g 7: h 8: i 9: j 10: k 11: l 12: m 13: n 14: o 15: p 16: q 17: r 18: s 19: t 20: u 21: v 22: w 23: x 24: y 25: z >>> for step in enumerate(alpha): ... print('{}: {}'.format(*step)) ... 0: a 1: b 2: c 3: d 4: e 5: f 6: g 7: h 8: i 9: j 10: k 11: l 12: m 13: n 14: o 15: p 16: q 17: r 18: s 19: t 20: u 21: v 22: w 23: x 24: y 25: z

We can also unpack dictionaries in a similar matter:

>>> my_dict {'job': 'Developer', 'name': 'Dennis', 'age': 24, 'state': 'New South Wales'} >>> for key, value in my_dict.items(): ... print('{}: {}'.format(key.title(), value)) ... Job: Developer Name: Dennis Age: 24 State: New South Wales

Create a function named combo() that takes two iterables and returns a list of tuples. Each tuple should hold the first item in each list, then the second set, then the third, and so on. Assume the iterables will be the same length.

def combo(iter1, iter2): ret = [] length = len(iter1) counter = 0 while counter < length: ret.append((iter1[counter],iter2[counter])) counter += 1 return ret # better alternatives def combo(iterable_1, iterable_2): list_of_tuples = [] for index in range(len(iterable_1)): list_of_tuples.append((iterable_1[index], iterable_2[index])) return list_of_tuples def combo(iterable_1, iterable_2): list_of_tuples = [] for index, item2 in enumerate(iterable_2): list_of_tuples.append( (iterable_1[index], item2) ) return list_of_tuples def combo(iterable_1, iterable_2): return list(zip(iterable_1, iterable_2)) def combo(iter1, iter2): combo_list = [] for index, value in enumerate(iter1): tuple = value, iter2[index] combo_list.append(tuple) return combo_list