Techniques and patterns with lists

List methods

From Python Documentation:

  • Take a look at methods you may find useful, and note them down here. Try to “play around” with them later.

Indexing and slicing

  • What will be printed at each step?
israelite_kings = ["Saul", "David", "Solomon", "Rehoboam", "Abijah", "Asa", "Jehoshaphat", "Jehoram", "Ahaziah", "Joash", "Amaziah", "Uzziah", "Jotham", "Ahaz", "Hezekiah", "Manasseh", "Amon", "Josiah", "Jehoahaz", "Jehoiakim", "Jehoiachin", "Zedekiah"]

print(israelite_kings[1])
print(israelite_kings[-2])
print(israelite_kings[3:5])
print(israelite_kings[:4])
print(israelite_kings[8:])
print(israelite_kings[3:10:3])
  • A list slice always return a copy of the list in question. (Check its ids with id(), for example).
    • That means that if we type israelite_kings[:], we are returning a complete copy of the list (the same as typing israelite_kings[:].copy())

Looping lists

  • There are basically two ways. Do you remember the difference?

    • When should we use one and when should we use the other?
    for king in israelite_kings:
      print(king)
    
    for ind in range(len(israelite_kings)):
      print(israelite_kings)
  • What does the function enumerate() does?

for ind, king in enumerate(israelite_kings):
  print(f'{ind+1}th king was {king}.')
  • What does the zip() function does? What does simply calling zip() returns?
kings = ["Saul", "David", "Solomon", "Rehoboam", "Jeroboam"]
nations = ["all Israel", "all Israel", "all Israel", "Judah", "north Israel"]
for k, n in zip(kings, nations):
  print(f'{k} ruled over {n}.')
  • What if I want to print sorted names?
for king in sorted(israelite_kings):
  print(king)
  • What is the different between the .sort() method and the sorted() method? (Hint: check the list objects).

  • Important: it is sometimes tempting to change a list while you are looping over it; however, you can run into lots of problems! It is often simpler and safer to create a new list instead.

    • For example, what is wrong in the following code?
for ind in range(len(israelite_kings)):
  israelite_kings.pop(ind)

Pattern: stacks

  • The following program is used to check if parentheses are matched.
def is_valid_parentheses(s):
    stack = []
    mapping = {')': '(', '}': '{', ']': '['}
    for char in s:
        if char in mapping.values():
            stack.append(char)
        elif char in mapping.keys():
            if not stack or mapping[char] != stack.pop():
                return False
        else:
            return False
    return len(stack) == 0
  • Notice the functions append() and pop()

  • Notice the boolean value that is being returned — the length of the stack should be zero if parentheses are matched

  • Try to use the function with some examples.

  • Can you think about a way of using a stack in programming? What examples from everyday life are stacks?

Queues

  • Another way to use lists is considering them as queues, instead of stacks.
    • Stacks are FIFO: First-In, First-Out
    • Queues are LIFO: Last-In, First-Out
  • Our event handlers, seen previously, can be understood as a queue. See the example:
# Initialize an empty event queue
event_queue = []

# Function to add an event to the queue
def add_event(event):
    event_queue.append(event)
    print(f"Event added: {event}")

# Add some events to the queue
add_event("Event 1")
add_event("Event 2")
add_event("Event 3")

# Process events from the queue
while len(event_queue) > 0:
  event = event_queue.pop(0)
  print(f"Processing event: {event}")
Event added: Event 1
Event added: Event 2
Event added: Event 3
Processing event: Event 1
Processing event: Event 2
Processing event: Event 3
  • What are other examples of queues - in programming and in everyday life?