Reputation: 516
To illustrate my problem, imagine I have a list
and I want to compare each element with the next one to check if they are the same value. The problem is that when I try to access the last element of the list and compare it with "the next one", that one is out of range, so I would get an error. So, to avoid this, I put a condition when accessing that last element, so I avoid the comparison.
list = [1, 2, 1, 1, 5, 6, 1,1]
for i in range(len(list)):
if i == len(list)-1:
print('Last element. Avoid comparison')
else:
if list[i] == list[i+1]:
print('Repeated')
I guess that there should be a more efficient way to do this. For instance, I was trying to set the condition in the definition of the for loop, something like this:
for i in range(len(list)) and i < len(list)-1
But that is invalid. Any suggestion about how to do this in a more efficient/elegant way?
Upvotes: 0
Views: 3918
Reputation: 468
Other answers have solved this, but I think it's worth mentioning an approach that may be closer to idiomatic Python. Python provides iterable unpacking and other tools like the zip
function to avoid accessing elements of sequences by index.
# Better to avoid shadowing the build-in name `list`
a_list = [1, 2, 1, 1, 5, 6, 1, 1]
for value, following_value in zip(a_list, a_list[1:]):
if value == following_value:
print("Repeated!")
The more-itertools package also has a useful function for this called pairwise.
Upvotes: 1
Reputation: 3288
You can utilize the functionality of range
as follows:
for i in range(1, len(list)):
if list[i-1] == list[i]:
print('Repeated')
In this way, you won't overrun the list.
Upvotes: 1
Reputation: 298
If you use only numbers in your list, you might want to work with numpy
for instance:
import numpy as np
np_arr = np.array(lst) # don't use 'list' for your object name.
diffs = np.diff(np_arr)
diffs_indices = np.where(diffs != 0)[0]
It is unclear what your exact uses, but for example in my code, you will get:
>>> diffs_indexes
array([0, 1, 3, 4, 5])
Which are the indices where elelment[i] != element[i+1]
Upvotes: 0
Reputation: 821
list = [1, 2, 1, 1, 5, 6, 1,1]
for i in range(len(list)):
if list[i] in list[i+1:i+2]:
print('repeated')
Upvotes: 0
Reputation: 42143
There are many ways to do this. The most common one is to use zip to pair each item with its successor:
if any(item == successor for item,successor in zip(lst,lst[1:])):
print('repeated')
groupby
from itertools is also a popular choice (but not optimal for this):
if any(duplicate for _,(_,*duplicate) in itertools.groupby(lst)):
print('repeated')
A for-loop would only need to track the previous value (no need for indexing):
prev = object() # non-matching initial value
for x in lst:
if prev==x: # compare to previous
print('repeated')
break
prev = x # track previous for next iteration
Iterators can be interesting when traversing data in parallel (here the elements and their predecessors):
predecessor = iter(lst) # iterate over items from first
for x in lst[1:]: # iterate from 2nd item
if x == next(predecessor): # compare to corresponding predecessor
print('repeated')
break
Upvotes: 0
Reputation: 2834
If you need to start from 0, you should use:
for i in range(len(list) - 1):
if list[i] == list[i + 1]:
print('Repeated')
The parameter stop
of range function is just integer, so you can use value len(list) - 1
instead of len(list)
to stop iterating on last but one element.
Upvotes: 2
Reputation: 141
so given that case ... if i == len(list)-1:
this condition will be True when the index is 7 (not the index that you want)
Just change that to if i == len(list)-2:
Upvotes: 0
Reputation: 188
This works!
list = [1, 2, 1, 1, 5, 6, 1, 1]
for i in range(len(list)):
if i+1 < len(list) and list[i] == list[i+1]:
print('Repeated')
Upvotes: 0
Reputation: 11
start from one and look backwards
for i in range(1, len(list)):
if list[i-1] == list[i]:
print('Repeated')
Upvotes: 0