-4

I want to check if a certain range in a list is the same. For example: In a list I have [X,Y,X,X,X,Y,Y], and I want to see if the third, fourth, and fifth are the same.

I have tried the following:

list = ['X', 'Y', 'X', 'X', 'X', 'Y']
for i in list, range(2,4):
    if not i == 'X':
        print("Test")

It does work, prints Test twice.

Test
Test

I just don't want to write a bunch of this:

if ... and .... and ..... and ... or .... and ...

martineau
  • 119,623
  • 25
  • 170
  • 301
Beni Rae
  • 1
  • 1
  • 1
    That's not how you slice lists. Read [Python's list slice notation](https://stackoverflow.com/questions/509211/understanding-pythons-slice-notation) to learn how. What you are actually doing is forming a tuple `(list, range(2, 4))` and iterating over that. Neither of those values is equal to `X`, so it prints twice. As an aside "not equals" is more naturally expressed as `i != 'X'` – Patrick Haugh Jul 09 '18 at 02:19
  • "I want to check if a certain range in a list" The problem here is trying to apply English grammar to a programming problem. The list does not *contain* any ranges, so the `range` function should not be expected to have **anything to do with** the solution. Though a range **contains indices** that could in turn be used to index the list and get its elements, a much more natural approach is to **slice** the list, and then do a test on the entire slice. – Karl Knechtel Jan 12 '23 at 00:00

2 Answers2

3

You are looping such that you test not list == 'X' then not range(2, 4) == 'X'; obviously, neither is equal, so you print both times. Your logic can be dramatically simplified though. If the goal is to see if indices 2, 3 and 4 are all equal, just convert that slice of the list to a set and check if the length is 1:

mylist = ['X', 'Y', 'X', 'X', 'X', 'Y']  # Changed list name; naming the list "list" leads to tears
if len(set(mylist[2:5])) == 1:
    print("2, 3 and 4 equal")
else:
    print("At least one not equal to the others")

You may also wish to check that mylist is long enough (slicing will not raise an error if the slice doesn't get the three elements expected), as written this only tests that the list is at least 3 elements long and any elements from index 2 to 4 are equal if they exist.

If you know mylist will always have at least five elements, and you prefer an exception when it is not, another solution is to check:

if mylist[2] == mylist[3] == mylist[4]:
    print("2, 3 and 4 equal")
else:
    print("At least one not equal to the others")

It's more verbose, but Python's chained comparisons mean you only load each value once, and unlike the other solution, it short-circuits; if index 2 is not equal to index 3, it won't even bother to load index 4, let alone compare it to the others.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

I'm sure there is more elegant way to do that, but you can try that:

def check_same(mylist, start_index, end_index):
    value = mylist[start_index]   
    for element in mylist[start_index + 1 : end_index]:
    if not element == value:
        return False
    return True
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80