Monday 9/25¶
List, Tuples, Dictionaries, Sets¶
When to use each¶
- list - Order matters, duplicates allowed, access by index, mutable (changeable)
- tuple - Order matters, duplicates allowed, access by index, immutable (un-changeable)
- Tuples are used to provide the effect of multiple return values for functions
- dict - A collection of key/value pairs. No duplicate keys are allowed, order doesn't matter.
- set - No duplicates allowed, order doesn't matter.
Accessing Docstrings¶
Each collection type has built-in methods. Documentation can be
accessed by using help
in the shell:
class list(object)
| list(iterable=(), /)
|
| Built-in mutable sequence.
|
| If no argument is given, the constructor creates a new empty list.
| The argument must be an iterable if specified.
|
| Methods defined here:
|
| __add__(self, value, /) Each of the entries with double underscores
| Return self+value. corresponds to an operator. For example __add__
| describes how the + operator works for lists.
|
| append(self, object, /)
| Append object to the end of the list.
|
| clear(self, /)
| Remove all items from list.
|
| copy(self, /)
| Return a shallow copy of the list.
|
| count(self, value, /)
| Return number of occurrences of value.
|
| extend(self, iterable, /)
| Extend list by appending elements from the iterable.
|
| index(self, value, start=0, stop=9223372036854775807, /)
| Return first index of value.
|
| Raises ValueError if the value is not present.
|
| insert(self, index, object, /)
| Insert object before index.
|
| pop(self, index=-1, /)
| Remove and return item at index (default last).
|
| Raises IndexError if list is empty or index is out of range.
|
| remove(self, value, /)
| Remove first occurrence of value.
|
| Raises ValueError if the value is not present.
|
| reverse(self, /)
| Reverse *IN PLACE*.
|
| sort(self, /, *, key=None, reverse=False)
| Sort the list in ascending order and return None.
|
| The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
| order of two equal elements is maintained).
|
| If a key function is given, apply it once to each list item and sort them,
| ascending or descending, according to their function values.
|
| The reverse flag can be set to sort in descending order.
The Containment Operator¶
Containment checking can be performed with in
for all Collection types:
# Lists:
colors = ["red", "blue", "green"]
"red" in colors # True
"pink" in colors # False
# Tuples:
hats = ("fedora", "fez")
"fez" in colors # True
"cap" in colors # False
# Dictionaries:
ages = {"Jan": 13, "Milo": 15}
"Jan" in ages # True
13 in ages # False-- For dictionaries, containment operator acts on the keys, not values!
Collections Lab¶
In this lab you will write functions that involve working with
Python collection classes. One of the goals today is to make sure that
you are in the habit of testing locally and using flake8
to verify
that your formatting is correct. To that end, the Gradescope
autograder will only provide two free submissions. Additional
submissions will result in a small point deduction.
Part 1 - Counter¶
One common use of dictionaries is to maintain a collection of
counters. For example, we might want to keep track of the number of
absences for students in a computer science course. Each time a
student is absent, the appropriate counter should incremented by one.
In this case, the key is the students name and the value is
the total number of absences. Write a function named
increment_counter
that takes a dictionary and a student name as
arguments. If the student isn't already in the dictionary, he or she
should be added with a count of 1. If he or she is already in the
dictionary, the current count should be increased by one. In either
case, the function should return the updated count for that
student. Your function must be in a file named counter.py
. The
following interaction illustrates the expected behavior:
>>> counts = dict()
>>> increment_counter(counts, "Alice")
1
>>> counts
{'Alice': 1}
>>> increment_counter(counts, "Alice")
2
>>> counts
{'Alice': 2}
>>> increment_counter(counts, "Zed")
1
>>> counts
{'Alice': 2, 'Zed': 1}
Don't submit until you are confident that your functionality is
correct and your docstrings are complete and properly formatted! Here
are the instructions for installing and configuring flake8
and the
docstring requirements:
Part 2 - Neighbors¶
Create a file named neighbors.py
. This functions will contain two
functions get_adjacent
and get_neighbors
. First, complete and
test get_adjacent
, then work on get_neighbors
. You do not need to
complete docstrings for these functions.
get_adjacent
¶
The get_adjacent
function must take two arguments: the first will be
a list, and the second will be an integer value representing an index.
It must return a new list containing the two elements immediately to
the left and right of the provided index. If the provided index is at
either the beginning or end of the list, there will be only one
element in the list. If the provided the provided list only has one
element, then there are no adjacent items and the returned list will
be empty.
The following function can be used to test your implementation:
def test_get_adjacent():
"""Test the get_adjacent method."""
items = ["A", "B", "C", "D"]
# Easy cases where there are two adjacent
assert get_adjacent(items, 1) == ["A", "C"]
assert get_adjacent(items, 2) == ["B", "D"]
# Trickier cases where there is only one adjacent
assert get_adjacent(items, 0) == ["B"]
assert get_adjacent(items, 3) == ["C"]
# Case where there are no adjacent
short = ["X"]
assert get_adjacent(short, 0) == []
You can call it from your main block as follows:
if __name__ == "__main__":
test_get_adjacent()
get_neighbors
¶
As part of your work for a political campaign you need to create a
mailing list that includes the neighbors of known donors to your
party. Create a function named get_neighbors
that takes two
arguments: the first is a list of mailing addresses that is ordered
according to the positions of houses on a particular street. The
second is a string representing the addresses of one of the houses
from the list. Your function must return a new list containing the
immediate neighbors of the provided address. Don't code this function
from scratch. You should be able to use the index
method of the
provided list along with the get_adjacent
function you already
completed. It should be possible to write your function so that it only contains a single line.
Here is a testing function that you can use to evaluate your finished code:
def test_get_neighbors():
"""Test the get_neighbors method."""
homes = ["121 Main", "123 Main", "125 Main", "127 Main"]
# Easy cases where there are two neighbors
assert get_neighbors(homes, "123 Main") == ["121 Main", "125 Main"]
assert get_neighbors(homes, "125 Main") == ["123 Main", "127 Main"]
# Trickier cases where there is only one neighbor
assert get_neighbors(homes, "121 Main") == ["123 Main"]
assert get_neighbors(homes, "127 Main") == ["125 Main"]
# Case where there are no neighbors
short_street = ["237 Broad"]
assert get_neighbors(short_street, "237 Broad") == []