-1

How can I compare two adjacent elements in an array without running into index out of range error.

I am trying to do something like this:

def count(n):
    counter = 1
    for i in range(len(n)):
        if n[i] == n[i+1]:
            counter += 1
    print(counter, n[i])

I can see that the problem is when it access the last element in n it can no longer find index i+1 and that's why it generates this error. but I need to know how to avoid this error while still checking the last element in the array or string( without changing the range to the length of n minus 1.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Ruf
  • 17
  • 4
  • 3
    "without changing the range to the length of n minus 1" Why that restriction? That seems like exactly what you need. – Bill the Lizard Sep 19 '21 at 21:14
  • By that, I mean that I still want to check the last element and not totally ignore it. but it doesn't have to be using the same for loop. – Ruf Sep 19 '21 at 21:48
  • `n[i] == n[i+1]:` - if you are at n == len(list)-1 this will try to access outside the list. change the loop to go only up to `for i in range(len(n)-1):` to fix. – Patrick Artner Sep 19 '21 at 21:58
  • @Ruf when you use `range(len(n) - 1)` the last element is accessed with `n[i+1]`, thus you basically iterate through the whole range of elements. – Farzin Sep 19 '21 at 22:01
  • 2
    Check the last element against what? You simply have to avoid using `n[i+1]` if `i == len(n) - 1`. – chepner Sep 19 '21 at 22:06
  • but the last element is not being printed now and that's the problem. I am using print here for simplification but I plan to do a more complicated thing to elements other than printing. – Ruf Sep 19 '21 at 22:09

4 Answers4

1

Alternatively you could this simple zip to compare those two adjacent numbers at the same time, and not worrying about index out of bound:

def count_adjacent(nums):
    count = 0
    for a, b in zip(nums, nums[1:]):
        if a == b: count += 1
    return count

>>> 
>>> count_adjacent([1,1,1,2,2,3, 4, 4, 5])
                      ^ ^   ^       ^
4

Second approach to use pairwise

from itertools import pairwise

def count_adj(L):
    return sum(a == b for a, b in pairwise(L))   # more efficient
Daniel Hao
  • 4,922
  • 3
  • 10
  • 23
  • 1
    Use `itertools.islice(nums, 1, None)` instead of `nums[1:]` to avoid making a copy of (most of) `nums`. – chepner Sep 19 '21 at 22:06
  • Agreed. Just try to offer a simpler approach to new learner here. – Daniel Hao Sep 19 '21 at 22:08
  • Or do this one line: >>> sum(a == b for a, b in zip(nums, nums[1:])) – Daniel Hao Sep 19 '21 at 22:10
  • 1
    That's a great way to work around the loop issue. because I want to make sure that the last element is being looked at. I will try it with the more complicated code I am working on. Thanks – Ruf Sep 19 '21 at 23:22
  • You can also try the *itertools* *pairwise*, eg. ```sum(a== b for a, b in (pairwise(L)))``` that's more efficient and faster. – Daniel Hao Dec 13 '22 at 16:05
0
def count(n):
    counter = 1
    for i in range(len(n) - 1):  # changed here
        if n[i] == n[i+1]:
            counter += 1
    print(counter, n[i])

Note that the last element of the list isn't ignored - it's compared with the second-to-last lement of the list.


range(len(n)) will generate 0, 1, ..., len(n) - 1. Note that len(n) - 1 is the last index in the list, since lists are zero-indexed.

Similarly, range(len(n) - 1) will generate 0, 1, ..., len(n) - 2.

The last iteration of the loop will have i = len(n) - 2. Note that n[i+1] will access the last element of the list, because len(n) - 2 + 1 == len(n) - 1.

Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • but the last element is not being printed now and that's the problem. I am using print here for simplification but I plan to do a more complicated thing to elements other than printing. – Ruf Sep 19 '21 at 22:08
0

Just change

if n[i] == n[i+1]:

to

if (n[i] == n[i+1])& (i!=n):

or

if (n[i] == n[i+1]) and (i!=n):
masoud
  • 55,379
  • 16
  • 141
  • 208
0
def count(n):
    counter = 1
    for i in range(len(n)):
        for j in range(len(n)):
           if i == j: counter += 1
              
    return counter

or if the array can be combined to a list, you could use this

   def counter(n):
       count = 0
       for num, num1 in zip(n, n[1:]):
          if num == num1:
            count += 1
          return count
derek
  • 21
  • 7