I'm doing the google code U python class and came across a problem trying the following problem, which is the commented out region, the solution needs to be a function. I'm on the second part and trying to find a way to count the values which meet the requirement,i[0:2]==i[-2:]. I running Python 3.2

# A. match_ends
# Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
# Note: python does not have a ++ operator, but += works.
def match_ends(words):
    words=sorted(words, key=len)
    for i in words:
        if len(i)<2:
            print(i)
            words=words[1:]
            print(words)
            for i in words:
                if i[0:2]==i[-2:]:
                    x=[]
                    x.append[i]#which I know will not work

Dani AI

Generated

Short summary and a clean, robust approach.

The goal is simply: count strings of length >= 2 whose first and last characters are the same. Sorting by length is unnecessary. Two common pitfalls seen above are (1) using slices like i[0:2] == i[-2:] — that compares two-character prefixes/suffixes, not the first vs the last character — and (2) mutating the list while iterating (for example reassigning words = words[1:] inside the loop), which can skip elements or produce confusing behavior. Also, the function should return the count rather than printing it.

A compact, safe implementation that avoids those problems:

def match_ends(words):
    """Return number of strings (len >= 2) whose first and last char match."""
    return len(list(filter(
        lambda w: isinstance(w, str) and len(w) >= 2 and w[0] == w[-1],
        words
    )))

# Example: match_ends(['abba', 'abcba', 'z', 'zz', 'xyx', 'ab'])  # -> 4

Notes and troubleshooting:

  • If inputs might include non-strings, keep the isinstance check (above) to avoid TypeError on indexing.
  • To avoid building an intermediate list (better for very large inputs), use a generator with sum(1 for w in words if ... ) so memory stays low.
  • Time complexity is O(n); the filter/list conversion adds O(n) memory unless a generator is used.
  • was correct to point out word[0] == word[-1] and to prefer returning the result; ’s experiments reveal why in-loop list mutation and wrong slicing lead to bugs.

Recommended Answers

All 5 Replies

I do not get the need of sorted etc from the requirement, I read it like:

# A. match_ends
# Given a list of strings, return the count of the number of
# strings where the string length is 2 or more and the first
# and last chars of the string are the same.
# Note: python does not have a ++ operator, but += works.
def match_ends(words):
    count = 0
    for word in words:
        if len(word) >= 2:
            count += word[:2] == word[-1:-3:-1]
    return count
commented: Incredibly helpful +1

in line ten is using the comparison == equivalent to saying 'only if'?

pytony, thank you. I tried your code and it didn't work for some reason, but nonetheless it was above my paygrade, but it did give me an idea and got me out of the rut I was stuck in. You're brilliant! here's the updated code and it works.

def match_ends(words):
    count=0
    words=sorted(words, key=len)
    for i in words:
        if len(i)<2:
            words=words[1:]
            for i in words[:]:
                if i[0:2]==i[-2:]:
                    count=count+1
    print(count)

I was way over complicating it by trying to put the strings that met the conditions in a new string,which I then intended to count. It's probably still over complicated, but I hope I get better over time, you've been a great help so far. I'm so glad I found this place.

The description looked unclear without input and output examples, and by influence of your code checking slice of length two, so I understood two or more letters must be same in ends in opposite order palindrome style, now I read it just

word[0] == word[-1] and len(word)>=1

You should return the answer though, not print the answer.

Simplest count of above understanding for me is:

def match_ends(words):
        return sum(len(word) >= 2 and word[0] == word[-1] for word in words)

I found this test in net, my one liner seems to pass (adapted print to pass for Python3 also):

def match_ends(words):
        return sum(len(word) >= 2 and word[0] == word[-1] for word in words)

# Simple provided test() function used in main() to print
# what each function returns vs. what it's supposed to return.
def test(got, expected):
  print('%5s got: %r expected: %r' % ('OK' if got == expected else 'X',
                                      got,
                                      expected))

# Calls the above functions with interesting inputs.
def main():
  print('match_ends')
  test(match_ends(['aba', 'xyz', 'aa', 'x', 'bbb']), 3)
  test(match_ends(['', 'x', 'xy', 'xyx', 'xx']), 2)
  test(match_ends(['aaa', 'be', 'abc', 'hello']), 1)

main()

EDIT: cleaned up the test code.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.