wambam97
wambam97

Reputation: 33

Accessing two following indexes in a loop

I'm new to python (although it's more of a logical question rather than syntax question I belive), and I wonder what's the proper way to access two folowing objects in a loop.

I can't really provide a specific example without getting too cumbersome with my explanation but let's just say that I usually try to tackle this with either [index + 1] or [index - 1] and both are problematic when it comes to either the last (IndexError) or first (addresses the last position right at the beginning) iterations respectively.

Is there a well known way to address this? I haven't really seen any questions regarding this floating around so it made me think it's basic logic I'm missing here.

For example this peice of code that wouldn't have worked had I not wrapped everything with try/except, and also the second inner loop works only since it checks for identical characters, otherwise it could have been a mess.

(explanation for clarity - it recieves a string (my_string) and a number (k) and checks whether a sequence of identical characters the length of k exists in my_string)

# ex2 5
my_string = 'abaadddefggg'
sub_my_string = ''
k = 9
count3 = 0

try:
    for index in range(len(my_string)):
        i = 0
        while i < k:
            sub_my_string += my_string[index + i]
            i += 1

        for index2 in range(len(sub_my_string)):
            if sub_my_string[index2] == sub_my_string[index2 - 1]:
                count3 += 1

        if count3 == k:
            break
        else:
            sub_my_string = ""
            count3 = 0

    print(f"For length {k}, found the substring {sub_my_string}!")

except IndexError:
    print(f"Didn't find a substring of length {k}")

Thanks a lot

Upvotes: 1

Views: 161

Answers (2)

ShlomiF
ShlomiF

Reputation: 2895

First off, by definition you need to give special attention to the first or last element, because they really don't have a pair.
Second-off, I personally tend to use list-comprehensions of the following type for these cases -

[something_about_the_two_consecutive_elements(x, y) for x, y in zip(my_list, my_list[1:])]

And last but not least, the whole code snippet seems like major overkill. How about a simple one-liner -

my_string = 'abaadddefggg'
k = 3

existing_substrings = ([x * k for x in set(my_string) if x * k in my_string])

print(f'For length {k}, found substrings {existing_substrings}')

(To be adapted by one's needs of course)


Explanation:
For each of the unique characters in the string, we can check if a string of that character repeated k times appears in my_string.
set(my_string) gives a set of the unique characters over which we iterate (that's the for x in set(my_string) in the list comprehension).
Taking a character x and multiplying by k gives a string xx...x of length k.
So x * k in my_string tests whether my_string includes the substring xx...x.
Summing up the list-comprehension, we return only characters for which x * k in my_string is True.

Upvotes: 2

Alex
Alex

Reputation: 7045

If I am understanding what you are trying to achieve, I would approach this differently using string slices and a set.

my_string = "abaadddefggg"
sub_my_string = ""
k = 3
count3 = 0

found = False
for index, _ in enumerate(my_string):
    if index + k > len(my_string):
        continue
    sub_my_string = my_string[index : index + k]

    if len(set(sub_my_string)) == 1:
        found = True
        break

if found:
    print(f"For length {k}, found the substring {sub_my_string}!")
else:
    print(f"Didn't find a substring of length {k}")

Here we use:

  • enumerate as this usually signals that we are looking at the indices of an iterable.
  • Check whether the slice will be take us over the string length as there's no point in checking these.
  • Use the string slice to subset the string
  • Use the set to see if all the characters are the same.

Upvotes: 1

Related Questions