Lists and Tuples

Lists Recap

A list is a sequence of values. These values can be anything: strings, numbers, booleans, even other lists.

To make a list you put the items separated by commas between brackets []

``````

In [ ]:

sushi_order = ['unagi', 'hamachi', 'otoro']
prices = [6.50, 5.50, 15.75]
print(sushi_order)
print(prices)

``````

You can access a single element in a list by indexing in using brackets. List indexing starts at 0 so to get the first element, you use 0, the second element is 1 and so on.

list[index]

``````

In [ ]:

print(sushi_order[0])
print(sushi_order[2])

``````

You can find the length of a list using len

len(list)

``````

In [ ]:

print(len(sushi_order))

``````

You can use negative indexing to get the last element of a list

``````

In [ ]:

print(sushi_order[-3])

``````

Nested lists

Lists can contain other lists as elements. This is a convenient alternative to a matrix. You can arrange lists of varying lengths (and contents) in a specific order and you can iterate over the elements (see below).

``````

In [ ]:

everyones_order = [['california roll'], ['unagi', 'dragon roll'], sushi_order]
print(everyones_order)

``````

To access an element in a nested list, first index to the inner list, then index to the item.

Example:

``    list_of_lists = [[1,2], [3,4], []]``

Acess the first index to the inner list and index to the item

```inner_list = list_of_lists[1] # [3,4]
print inner_list[0] # 3
```

Or even quicker:

```list_of_lists[1][0] # 3
```

To get dragon roll from the sushi order, first we get the second element (index 1) then we get the the second item (index 1)

``````

In [ ]:

everyones_order[1][1]

``````

TRY IT

Get the california roll from the list `everyones_order`. As a challenge print all the items from the second person's order.

``````

In [ ]:

``````

Mutable Lists

Lists are mutable, that means that you can change elements.

To assign a new value to an element

``````my_list = [1, 2, 3]
my_list[0] = 100``````
``````

In [ ]:

sushi_order[0] = 'caterpillar roll'
print(sushi_order)

``````

TRY IT

Update the last element in `prices` to be 21.00 and print out the new result

``````

In [ ]:

``````

Operators and Lists

The `in` operator allows you to see if an element is contained in a list

``````

In [ ]:

sushi_order

``````
``````

In [ ]:

print('hamachi' in sushi_order)

``````
``````

In [ ]:

if 'otoro' in sushi_order:
print("Big spender!")

``````

You can use some arithmatic operators on lists

The `+` operator concatenates two lists

The `*` operator duplicates a list that many times

``````

In [ ]:

print(sushi_order * 3)

``````
``````

In [ ]:

print(prices + sushi_order)

``````

Note: You can only concatenate lists with lists! If you want to add a "non-list" element you can use the append() function that we will learn about in the next section.

``````

In [ ]:

# WRONG
prices + 22

``````

Remember slices from strings? We can also use the slice operator on lists

``````

In [ ]:

inexpensive = sushi_order[:2] #takes only the first two elements from list
print(inexpensive)

``````

Don't forget, you can use the `for` and `in` keywords to loop through a list

``````

In [ ]:

for item in sushi_order:
print("I'd like to order the {}.".format(item))

print("And hold the wasabi!")

``````
``````

In [ ]:

for idx, item in enumerate(sushi_order):
print("I'd like to order the {0} for {1}.".format(item, prices[idx]))

``````

TRY IT

Create a variable called `lots_of_sushi` that repeats the inexpensive list two times

``````

In [ ]:

``````

Adding and deleting elements

To add an element to a list, you have a few options

1. the append method adds an element or elements to the end of a list, if you pass it a list, the next element with be a list (making a list of lists)

2. the extend method takes a list of elements and adds them all to the end, not creating a list of lists

3. use the `+` operator like you saw before

``````

In [ ]:

my_sushis = ['maguro', 'rock n roll']
print(my_sushis)
my_sushis.append(['hamachi', 'california roll'])
print(my_sushis)

``````
``````

In [ ]:

my_sushis = ['maguro', 'rock n roll']
my_sushis.extend(['hamachi', 'california roll'])
print(my_sushis)

``````

You also have several options for removing elements

1. the pop method takes the index of the element to remove and returns the value of the element

2. the remove method takes the value of the element to remove

3. the del operator deletes the element or slice of the list that you give it

del l[1:]

``````

In [ ]:

print(my_sushis)
last_sushi = my_sushis.pop(-1)
print(last_sushi)

``````
``````

In [ ]:

my_sushis.remove('maguro')
print(my_sushis)

``````
``````

In [ ]:

del my_sushis[1:]
print(my_sushis)

``````

TRY IT

Add 'rock n roll' to `sushi_order` then delete the first element of `sushi_order`

``````

In [ ]:

``````

List Functions

`max` will return maximum value of list

`min` returns minimum value of list

`sum` returns the sum of the values in a list

`len` returns the number of elements in a list # Just a reminder

``````

In [ ]:

numbers = [1, 1, 2, 3, 5, 8]

print(max(numbers))
print(min(numbers))
print(sum(numbers))
print(len(numbers))

``````

TRY IT

Find the average of `numbers` using list functions (and not a loop!)

(And if you are feeling self-loathing, look back at lesson 4 and see how many lines of code it took to do this without aggregation functions)

``````

In [ ]:

``````

Aliasing

If you assign a list to another variable, it will still refer to the same list. This can cause trouble if you change one list because the other will change too.

``````

In [ ]:

cooked_rolls = ['unagi roll', 'shrimp tempura roll']
my_order = cooked_rolls
my_order.append('hamachi')
print(my_order)
print(cooked_rolls)

``````

To check this, you can use the `is` operator to see if both variable refer to the same object

``````

In [ ]:

print(my_order is cooked_rolls)

``````

To fix this, you can make a copy of the list using the list function

`list` takes a sequence and turns it into a list.

Alternatively you can use the `copy()` method: `my_order = cooked_rolls.copy()`

``````

In [ ]:

cooked_rolls = ['unagi roll', 'shrimp tempura roll']
my_order = list(cooked_rolls)
my_order.append('hamachi')
print(my_order)
print(cooked_rolls)

``````

Tuples

Tuples are very similar to lists. The major difference is that tuples are immutable meaning that you can not add, remove, or assign new values to a tuple.

The creator of a tuple is the comma `,` but by convention people usually surround tuples with parenthesis.

``````

In [ ]:

noodles = ('soba', 'udon', 'ramen', 'lo mein', 'somen', 'rice noodle')
print(type(noodles))

``````

You can create a tuple from any sequence using the `tuple` function

``````

In [ ]:

sushi_tuple = tuple(my_order)
print(sushi_tuple)
# Remember strings are sequences
maguro = tuple('maguro')
print(maguro)

``````

To create a single element tuple, you need to add a comma to the end of that element (it looks kinda weird)

``````

In [ ]:

single_element_tuple = (1,)
print(single_element_tuple)
print(type(single_element_tuple))

``````

You can use the indexing and slicing you learned for lists the same with tuples.

But, because tuples are immutable, you cannot use the append, pop, del, extend, or remove methods or even assign new values to indexes

``````

In [ ]:

print(noodles[0])
print(noodles[4:])

``````
``````

In [ ]:

# This should throw an error
noodles[0] = 'spaghetti'

``````

To change the values in a tuple, you need to create a new tuple (there is nothing stopping you from assigning it to the same variable, though

``````

In [ ]:

print(sushi_tuple)
sushi_tuple = sushi_tuple[1:] + ('california roll',)
print(sushi_tuple)

``````

You can loop through tuples the same way you loop through lists, using `for` `in`

``````

In [ ]:

for noodle in noodles:
print("Yummy, yummy {0}".format(noodle))

``````

TRY IT

Create a tuple containing 'soy sauce' 'ginger' and 'wasabi' and save it in a variable called `accompaniments`

``````

In [ ]:

``````

Zip

the zip function takes any number of lists of the same length and returns a generator for lists of tuples where the tuples will contain the i-th element from each of the lists.

This is really useful when combining lists that are related (especially for looping)

remider to print a generator, just cast the results as a list (you can cast them as a tuple instead, actually)

``````

In [ ]:

print(list(zip([1,2,3], [4,5,6])))

``````
``````

In [ ]:

sushi = ['salmon', 'tuna', 'sea urchin']
prices = [5.5, 6.75, 8]

sushi_and_prices = list(zip(sushi, prices))

sushi_and_prices

``````
``````

In [ ]:

for sushi, price in sushi_and_prices:
print("The {0} costs \${1}".format(sushi, price))

``````

Enumerate

While the zip function iterates over two lists, the built-in function enumerate loops through indices and elements of a list. It returns a list of tuples containing the index and value of that element.

``````for index, value in enumerate(list):
...``````
``````

In [ ]:

exotic_sushi = ['tako', 'toro', 'uni', 'hirame']
for index, item in enumerate(exotic_sushi):
print(index, item)

``````

Project: Party Budget

You are tasked with writing budgeting software, but at this point, things are a mess. You have two files. `budget_prices.txt` has a list of costs for each item separated by new lines (\n). `budget_items.txt` has a list of the items that were bought. Luckily they are both in order. You need to write a program that will take the files and a value for the overall budget and print out the total spent and how close they are to reaching the budget. In step 2 you will create a new file where the items and prices are in the same document and there is a sum printed out at the end.

Step 1

1. Create a function called `file_to_float_list` that takes in a file and returns a list containing a float for each line Hint Make sure to remove the newlines when casting as floats.
2. Store the budget of 2000.00 in a variable called `budget`.
3. Run file_to_float_list on budget_prices.txt and save the result in a variable called `prices`.
4. Calculate the `sum` of the prices array and store in a variable called `spent`.
5. Calculate the percentage of budget spent and store in a variable called `percent_spent`
6. Print out the results:

Budget: 2000.00 Spent: (amt spent) Percentage Spent: (percent spent)

7. Bonus Print out a progress bar for the budget. Print out '=' for every 10% spent and '-' for every 10% unspent. =====>-----

Step 2

1. Create a function called `file_to_string_list` that takes in a file and returns a list containing a string for each line with newlines removed.
2. Run `file_to_string_list` on budget_items.txt and save the result in a variable called `stuff_bought`.
3. Zip `stuff_bought` and `prices` together and store in a variable called `items_and_prices`
4. Loop through `items_and_prices` and print out the item, then a tab character '\t' and then the price (use string formatting)
5. Print another line 'Sum\t(amount spent)'
6. Print a final line 'Budget\t(budget)'

7. Bonus Print everything you printed for step 2 into a new file. (Then open the file in excel.)

``````

In [ ]:

``````