0

In a for loop, I'm trying to understand when to refer to an item by its item name and when to refer to the item as an index of the list I'm looping through.

In the code pasted below, I don't understand why "idx" is referred to in the "if" statement with a reference to the list index but then in the definition of maximum_score_index, it is referred to by itself.

def linear_search(search_list):

  maximum_score_index = None

  for **idx** in range(len(search_list)):

    if not maximum_score_index or **search_list[idx]** > search_list[maximum_score_index]:

      maximum_score_index = **idx**
  return maximum_score_index

I'd love to have an explanation so I can differentiate in the future and some examples to show the difference so I can understand.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
H. Farrow
  • 21
  • 3
  • 1
    A for loop iterates over the items themselves - https://docs.python.org/3/tutorial/controlflow.html#for-statements . If you also need to know the item's index, use [enumerate](https://docs.python.org/3/library/functions.html#enumerate) – wwii Mar 24 '19 at 03:38
  • Watch out for the bug in the sample function. `maximum_score_index` is `false` when set to index 0 (in addition to None). So, it won't work when the max value is at index zero. – DaveStSomeWhere Mar 24 '19 at 04:40

2 Answers2

0

In Python, range(num) (more or less) returns a list of numbers from 0 through num - 1. It follows that range(len(my_list)) will generate a list of numbers from 0 through the length of my_list minus one. This is frequently useful, because the generated numbers are the indices of each item in my_list (Python lists start counting at 0). For example, range(len(["a", "b", "c"])) is [0, 1, 2], the indices needed to access each item in the original list. ["a", "b", "c"][0] is "a", and so on.

In Python, the for x in mylist loop iterates through each item in mylist, setting x to the value of each item in order. One common pattern for Python for loops is the for x in range(len(my_list)). This is useful, because you loop through the indices of each list item instead of the values themselves. It's almost as easy to access the values (just use my_list[x]) but it's much easier to do things like access the preceding value (just use my_list[x-1], much simpler than it would be if you didn't have the index!).

In your example, idx is tracking the index of each list item as the program iterates through search_list. In order to retrieve values from search_list, the program uses search_list[idx], much like I used my_list[x] in my example. The code then assigns maximum_score_index to the index itself, a number like 0, 1, or 2, rather than the value. It's still easy to find out what the maximum score is, with search_list[maximum_score_index]. The reason idx is not being used as a list accessor in the second case is because the program is storing the index itself, not the value of the array at that index.

Luke Taylor
  • 8,631
  • 8
  • 54
  • 92
  • Thanks! That makes sense. I think I was getting tripped up on the index vs. value part of it and your example with the range() cleared it up. – H. Farrow Mar 24 '19 at 04:42
0

Basically, this line:

if not maximum_score_index or **search_list[idx]** > search_list[maximum_score_index]:
    maximum_score_index = **idx**

Can be thought of as:

if (this is the first pass) or (element at index > this loop-iteration element):
    keep this index as largest element

What I recommend to do:

  1. Go through the code, on a piece of paper and iterate over a list to see what the code does
  2. Write the code in any IDE, and use a debugger to see what the code does

Are you looking for the index of the highest element in the list or the value? If you are looking for the value, it can be as simple as:

highest = max(search_list)

You could also use enumerate, which will grant you "free" access to the current index in the loop:

>>> search_list
[10, 15, 5, 3]
>>> maximum_score_index = None
>>> for idx, value in enumerate(search_list):
...   if not maximum_score_index or search_list[idx] > value:
...     maximum_score_index = idx
... 
>>> maximum_score_index
1
>>> search_list[maximum_score_index]
15
camelBack
  • 748
  • 2
  • 11
  • 30