1

Given a list of strings, return the count of the number of strings where the string length is 3 or more and the first and last chars of the string are the same.

To solve this problem I created the following function,

def match_ends(words):
  FirstL=words[0:1]
  LastL=words[-1:]
  x=len(words)>3 and FirstL == LastL
  count=0
 for x in words:
    count+=1
    return count

then tested it here,

def test(got, expected):
  if got == expected:
    prefix = ' OK '
  else:
    prefix = '  X '
  print ('%s got: %s expected: %s' % (prefix, repr(got), repr(expected)))


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


  print

Result:

X  got: 1 expected: 3
OK  got: 1 expected: 1
OK  got: 1 expected: 1
Jason
  • 2,170
  • 2
  • 15
  • 24

2 Answers2

0

You have a few problems here:

  1. When you're looping over each of the words, you return count within the loop, instead of at the end when the loop finishes. This is why you were always getting 1.

  2. You always count += 1 even if x is False.

  3. x is taking the first and last item of the list, rather than the first and last letter in each word in the list.

  4. Finally you shadow the bool x in your for loop.


Tips

Why not split this into two functions?

def match_end(word):
    first, last = word[0], word[-1:]
    return True if first == last and len(word) >= 3 else False

def match_ends(words):
    count = 0
    for word in words:
        count += 1 if match_end(word) else 0
    return count

The first function, match_end(word) returns a bool of either True or False.

  • First, It sets the variables first and last to the first and last letter of the string via slicing.

  • Next, it returns True if the first letter is the same as the last, and if the length of the word is less than three. Otherwise, it returns False. This is done with Python's Ternary Operator.

The second function, match_ends(words), takes in a list of strings(like your original one) iterates over each word in the list.

  • For each word in the list, it tests to see if match_end(word) returns True.

    • If so, it increments the count by 1.

    • Otherwise, it does nothing (increments count by 0).

  • Finally, it returns count.

Community
  • 1
  • 1
Jason
  • 2,170
  • 2
  • 15
  • 24
-1

Your best bet here is to use a list comprehension. A list comprehension has three parts:

  • The transformation that you want to perform on each element of the input,
  • the input itself, and
  • an optional "if" statement that indicates when to produce output

So for example, we can say

[ x * x               # square the number
for x in range(5) ]  # for each number in [0,1,2,3,4]  `

which will produce the list

[0 1 4 9 16]

We can add a third (filtering) line, and get only odd numbers back:

[x * x
for x in range(5) 
if x % 2]     # divide x by 2, take the remainder -- if 1, output the number`

In your particular case, we don't care about the transformation part. We just want to output the word if it fits your criteria:

[word
 for word in word_list
 if len(word) >= 3 and word[0] == word[-1] ]

This will give you a list back. Now you just need to get the length of that list:

len( [word
 for word in word_list
 if len(word) >= 3 and word[0] == word[-1] ]  )

Want to turn that into a function? Here you go:

def count_matching_words(word_list):
    return len([word
                for word in word_list
                if len(word) >= 3 and word[0] == word[-1]])
Akshat Mahajan
  • 7,939
  • 2
  • 30
  • 38
reuven
  • 44
  • 5
  • 1
    While I approve of the way you broke this down, I must protest against splitting up your list comprehensions this way. This code can be clear even if condensed into one line - about the only time multiline list comprehensions should happen is when the run the risk of exceeding 72 characters per line. – Akshat Mahajan Apr 22 '16 at 03:58
  • As someone who has been teaching Python professionally for more than 10 years, I strongly disagree. List comprehension syntax consistently baffle newcomers (and not-so-newcomers) to the language, and I've found that breaking them down in this way dramatically helps them to understand what's going on. The moment that I started (about two years ago) to write my list comprehensions in this way, my students' understanding improved a great deal. – reuven Apr 22 '16 at 04:15