-1

i am trying to write a function that will analyze a string to check if it contains two of the same letter in a row. i wrote the function for it but it doesnt work, any idea why?

import itertools
def double_letters(word):
word = list(word)
for index, item in enumerate(word):
    for next_item in word[index + 1:]:
        if item == next_item:
            return True
        else:
            return False
crass93
  • 1
  • 3
  • 1
    Why do *you* think it doesn't work? SO is not a free debugging service. Use a debugger, work through your example by hand, use print statements. Only after you've exhausted all reasonable options should you look to SO. – Mad Physicist Dec 10 '21 at 18:31
  • it doesnt throw any error, it just gives a wrong value. is there something i am not seeing? – crass93 Dec 10 '21 at 18:43
  • @MadPhysicist is absolutely correct that struggling with this stuff is the best way to learn and keeps the content on here higher quality. That said, the thing you're not seeing is that an `if else` where both paths return a value will not continue iterating ever. – ᴓᴓᴓ Dec 10 '21 at 18:44
  • 1
    @wooooooo. I assure you that I see that and many other problems with the code. I am voting to close the question because it shows no attempt to solve the problem, as required by the rules described in [ask]. The purpose of this site is to provide valuable information for people experiencing programming problems, not to do homework for unmotivated students. – Mad Physicist Dec 10 '21 at 18:47
  • @MadPhysicist I agree with you, it wasn't meant to be a criticism, the opposite if anything. I'm just trying to help OP despite the rules because the "do my homework" questions I've seen are far worse. edit: Oh I see the confusion, sorry if that came across as rude. I meant "the thing you're not seeing" as a reply to OP. – ᴓᴓᴓ Dec 10 '21 at 18:50
  • 1
    @wooooooo. Ah. If that was addressed to OP it makes more sense – Mad Physicist Dec 10 '21 at 18:54
  • Does this answer your question? [Iterate string to compare an i element to i+1 element python](https://stackoverflow.com/questions/70277622/iterate-string-to-compare-an-i-element-to-i1-element-python) – itprorh66 Dec 10 '21 at 19:05
  • i spent alot of time trying to crack this up, i could understand your criticism if it ended up being some syntax error, i am sorry if my programming problems are not up to your mettle, but i have spent hours cracking this up, and i have seen questions on stack overflow that could be solved with google search. how can it show "no attempt to solve the problem" when i posted the code? – crass93 Dec 10 '21 at 19:14
  • Related: [Iterate a list as pair (current, next) in Python](https://stackoverflow.com/questions/5434891/iterate-a-list-as-pair-current-next-in-python) – wwii Dec 10 '21 at 19:28
  • `for index, item in enumerate(word[:-1]): if item == word[index+1]: return True` - then a `return False` at the appropriate indentation level. – wwii Dec 10 '21 at 19:34

3 Answers3

1

You're doing a few weird things here, but the main one is the secondary loop. Why do you need that if you have the index? You know the next index is just +1 and you don't even use both (index & value) here.

The second biggest problem is returning false if the characters don't match; this will return the matching result only for the first two characters, but you're looking for the first match, so you should only return on a match. You can use a variable to track this, but you can also simply return true when needed and return false if that condition is never met.

Last, you don't need enumerate, although it's fine. For this approach I would just enumerate to the 2nd last index (enumerate(word[0:len(word)-1]). Or, don't use enumerate like in the example below:

import itertools
def double_letters(word):
    word = list(word)
    for index in range(len(word)-1):
        if word[index] == word[index+1]:
            return True
    return False;
print(double_letters('world hello '))
ᴓᴓᴓ
  • 1,178
  • 1
  • 7
  • 18
  • 1
    I was trying to iterate over a word to find the index of each letter and then use the second loop to find the next item and compare them with if statement but i guess i messed up. my loops never saw any other letters beyond the first ones so they were throwing false. this is exactly the answer i was looking for, thank you. you the beast! – crass93 Dec 10 '21 at 18:55
1

There are three problems with this function, and two of them are on this line:

for next_item in word[index + 1:]:
  • You're iterating over all of the letters following item, when the only next_item you're concerned with is the immediate next letter (i.e. word[index+1], not the entire slice word[index+1:]
  • word[index+1] is going to walk off the edge of the word, leaving you with no next_item to compare. To fix this, you could check to see if you're at the end and special-case it, or you could just iterate over word[:-1] (everything but the last letter) in the outer loop.

The final problem (and the one that's causing your immediate bug) is with this if/else:

        if item == next_item:
            return True
        else:
            return False

No matter what, you will immediately return upon making the first comparison -- hence this function will only count a double letter if it's the first two letters. It'll never get to compare anything else. To fix this, remove the else, and have the return False happen at the very end of the function, so that we only return False if we haven't found a reason to return True.

All together:

def double_letters(word):
    for index, item in enumerate(word[:-1]):
        next_item = word[index+1]
        if item == next_item:
            return True
    return False


assert double_letters("hello")
assert not double_letters("abcdef")

A solution with itertools might be to use groupby, which groups an iterable into identical items; you can check to see if any of the groups are longer than 1 item like this:

import itertools

def double_letters(word):
    for _, g in itertools.groupby(word):
        if len(list(g)) > 1:
            return True
    return False

But the easiest way to write this type of sequential-item check is to zip the iterable with a slice of itself, like this:

def double_letters(word):
    for item, next_item in zip(word, word[1:]):
        if item == next_item:
            return True
    return False

or more simply, using any:

def double_letters(word):
    return any(item == next_item for item, next_item in zip(word, word[1:]))
Samwise
  • 68,105
  • 3
  • 30
  • 44
0

If you don't have an equality once, you cannot stop directly by returning false. You need to wait the end. Also don't need a nested loop, use zip to iterate on 2 consecutive chars of a string

def double_letters(word):
    for current_ch, next_ch in zip(word, word[1:]):
        if current_ch == next_ch:
            return True
    return False
azro
  • 53,056
  • 7
  • 34
  • 70
  • I you have a nested loop, you misread the question. – Mad Physicist Dec 10 '21 at 18:33
  • @MadPhysicist hum ? Like what word doesn't work my the solution I proposed ? The OP asked if the set of char is unique or not – azro Dec 10 '21 at 18:35
  • "check if it contains two of the same letter in a row" is not what your code is doing. – Mad Physicist Dec 10 '21 at 18:35
  • i want the function to return true if there are two same letters consecutively, else i want to return false. for example, fucntion, upon being called with argument "hello" should return true, because word hello has two consecutive L letters in it, however it returns false for some reason, any idea why? – crass93 Dec 10 '21 at 18:37
  • It's because you only check the first two letters in the word, and return based off that. You can see my answer for more detail. Azro's advice was good but I'm not sure why he kept the nested loop, it seems entirely pointlessly to me. – ᴓᴓᴓ Dec 10 '21 at 18:40
  • @MadPhysicist didn't understood the meaning of "in a row", I'm not an english speaker :) – azro Dec 10 '21 at 18:44
  • 1
    thx wooooooo, i completely forgot that my loop stops after first iteration. and doesnt go through to other letters. thanks a bunch. – crass93 Dec 10 '21 at 18:47
  • @crass93 I've updated my answer, to make it correct ;) – azro Dec 10 '21 at 18:48
  • azro pretty sweet solution, didnt know you can use zip function to zip the same list. – crass93 Dec 10 '21 at 19:19