2

I'm trying to write a program which counts the times in a list where an item is greater than their adjacent neighbours on either side:

inp = [1, 2, 3, 2, 8, 7, 6, 9, 5]

def check(n):
    count = 0
    ind_num1 = 0
    ind_num2 = 2
    index1 = n[ind_num1]
    index2 = n[ind_num2]
    for i in n[1:-1]:
        if i > index1 and i > index2:
            count += 1
        ind_num1 += 1
        ind_num2 += 1
    return count

print(check(inp))

My solution is to check whether value in the for loop (i) is greater than the indexes above and below it, while adding one to each adjacent index each time through the loop. ind_num1 and ind_num2 show the correct values as the loop progresses. However, index1 and index2 remain the same instead of incrementally increasing in line with the value of ind_num1 and `ind_num2'. Why don't they change?

3
  • I've just realised that the values for index1 and index2 are 1 and 3 because those are the values for 0, 2 on the list. But the same question applies in the title, how come they are not changing? Commented Oct 7, 2019 at 21:00
  • Do you want to compare inp[0] to inp[-1] and inp[1]? Commented Oct 7, 2019 at 21:00
  • No inp[0] does not have two neighbours, and neither does inp[-1] Commented Oct 8, 2019 at 7:52

1 Answer 1

2

The reason why ind_num1 and ind_num2 seemingly have no effect on index1 and index2 is because you're incrementing the former two variables within the loop, but you've assigned the values of index1 and index2 outside of the loop. Hence index1 and index2 will always remain to be 0 and 2 respectively. If you want to index1 and index2 to accurately reflect the values of ind_num1 and ind_num2, you need to update the values of index1 and index2 within the loop, with every iteration of the loop.

inp = [1, 2, 3, 2, 8, 7, 6, 9, 5]

def check(n):
    count = 0
    ind_num1 = 0
    ind_num2 = 2
    for i in n[1:-1]:
        index1 = n[ind_num1]
        index2 = n[ind_num2]
        if i > index1 and i > index2:
            count += 1
        ind_num1 += 1
        ind_num2 += 1
    return count

print(check(inp))

If you want to also compare the first item in the list to the last item and second item, and the last item in the list to the second to last item and first item, it would be as simple as...

inp = [1, 2, 3, 2, 8, 7, 6, 9, 5]

def check(n):
  count = 0
  for e,i in enumerate(inp):
    follIndex = e+1 if e+1 < len(n) else 0 # Changes index of following item to 0 if comparing last item in the list.
    if i > inp[e-1] and i > inp[follIndex]:
      count += 1
  return count

print(check(inp)) # Returns and prints '3' because three values (3, 8, 9)
                  # are bigger than both of the adjacent values in the list.

You can keep track of the current index by enumerating the list, whereby the value of e is an integer that always represents the index of the current item.

The purpose of tracking the current index, or e, is so that you can easily access the adjacent list items via inp[e-1] and inp[e+1].

This allows you get rid of many unnecessary variables.


Since you don't want to compare the first or last items, this is what you would do:

inp = [1, 2, 3, 2, 8, 7, 6, 9, 5]

def check(n):
  count = 0
  for e,i in enumerate(n[1:-1]):
    if i > n[e] and i > n[e+2]:
      count += 1
  return count

print(check(inp))

You use enumerate to quantify the iterations (i.e. 0, 1, ... 6) as e. This value (i.e. e) is used to determine the adjacent list items (i.e. n[e] and n[e+2]), which allows you to get rid of all those unnecessary variables. FWIW, i is essentially equal to e+1.

Sign up to request clarification or add additional context in comments.

2 Comments

@Harry I'm pretty sure you can still mark it as the answer since I did answer your question and all...?
@Harry refer to my last comment

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.