Iteration Using Indexes

Indexing Into a Sequence

How do we retrieve an element at a specific place from a list or a string? For example, to get the second element from the list a = [1, 2, 3], what code would I write? →

a[1]

Indexes

What are some attributes of list and string indexes? That is… when you index into a sequence type…

* Indexes are ints
* They are sequential and consecutive

Generating a Sequence of Integers

One way of iterating over every item in a list or a string is to go through each element by indexing.

…But how would you generate all of those indexes and go through each one? →

Hint: there are two ways to do this using constructs / statements that we've used before.

For Loops and Indexes

Use a for loop to print out every element in the list a = ["quill", "qat", "quip"]: →

Some hints:

a = ["quill", "qat", "quip"]
for i in range(0, len(a)):
	print(a[i])

While Loops and Indexes

Use a while loop to print out every element in the list a = ["quill", "qat", "quip"]: →

Some hints:

a = ["quill", "qat", "quip"]
i = 0
while i < len(a):
	print(a[i])
	i += 1

The "Usual" Way

Finally, to round things out, use a for loop - without indexes - to print out every element in the list a = ["quill", "qat", "quip"]: →

a = ["quill", "qat", "quip"]
for word in a:
	print(word)

Incrementing Every Element

Let's try adding one to every element in a list.

Start with the following list of numbers: numbers = [9, 19, 29, 39]

We could do something like this:

numbers = [9, 19, 29, 39]
numbers[0] = numbers[0] + 1
numbers[1] = numbers[1] + 1
numbers[2] = numbers[2] + 1
numbers[3] = numbers[3] + 1

Incrementing Every Element Continued

But, of course, it would be better if we didn't have to manually re-assign every index explicitly. Maybe we can…

numbers = [9, 19, 29, 39]
for i in range(len(numbers)):
    numbers[i] = numbers[i] + 1
print(numbers)

Reversing a List

Write a function that takes a list as an input and returns the list in reverse order (btw, there's already a list method that does this) →

def rev(a):
	new_list = []
	for i in range(len(a) - 1, -1, -1):
		new_list.append(a[i])	
	return new_list
		
assert ["charlie", "bravo", "alpha"] == rev(["alpha", "bravo", "charlie"]), "reverses order of non-empty list"
assert [] == rev([]), "returns empty list for empty list"
print(rev(["alpha", "bravo", "charlie"]))

Another (More Destructive Way) to Reverse a List

Can you use pop to do it? →

def rev(a):
	new_list = []
	while(len(a) != 0):
		new_list.append(a.pop())
	return new_list

my_stuff = ["will", "soon", "disappear"]
print(my_stuff)
print(rev(my_stuff))
print(my_stuff)

But Wait - What Happened?

What's the output of the pop() version of the solution? →

def rev(a):
	new_list = []
	while(len(a) != 0):
		new_list.append(a.pop())
	return new_list

my_stuff = ["will", "soon", "disappear"]
print(my_stuff)
print(rev(my_stuff))
print(my_stuff)
['will', 'soon', 'disappear']
['disappear', 'soon', 'will']
[]

Iterating with Indexes vs Regular Iteration

How do you know which kind of loop to use when both loops (using indexes vs using elements) seem pretty similar?

for i in range(len(my_list)):

for element in my_list

If using an index is necessary… use the for i in range version. For example, some situations may be: