Home > database >  How to count words that end with a letter? (python)
How to count words that end with a letter? (python)

Time:10-21

I am a beginner and this is what I came up with so far. However, it does not output the correct number of words that end with "a" or "b." Any tips on how to correct this code?

names = input("Enter list of names: ")

name = names.split(" ")

num = len(name)

ab = ""

print("Number of words:", num)

for i in range(num):
    if name[i] == ' ':
        if name[i-1] == a:
            ab.append()   " "
        elif name[i-1] == b:
            ab.append()   " "

a_b = ab.split(' ')        

print("Number of words that end with a or b: ",len(a_b))

CodePudding user response:

In Python boolean (True and False) are the same as the integers 1 and 0. This means you can use sum() to count True booleans. str.endswith() returns a boolean. This means you can just do this:

words = ["stab", "drama", "hello", "magma", "test"]

a_b = sum(word.endswith(('a', 'b')) for word in words) 
# 3

z_c = sum(word.endswith(('z', 'c')) for word in words) 
# 0

CodePudding user response:

words = ["ab", "bab", "pa", "pap"]

result = 0
for word in words:
    if word[-1] in "ab":
        result  = 1

print(result)

CodePudding user response:

As a list comprehension:

words = ["word1a", "word2b", "word3", "word4", "word5a"]  # ['word1a', 'word2b', 'word5a']
filtered_words = [word for word in words if word[-1] in "ab"]
filtered_words = [word for word in words if word.endswith(("a", "b"))]  # better, if you have multiple endings you want to search for with different lengths
len(filtered_words)  # 3

CodePudding user response:

Any tips on how to correct this code?

Others have answered alternative, working solutions, but I want to try to point out the specific things wrong in your code snippet and tips to correct.

First here's a copy of your snippet with some simple debugging prints along with their output (running in python 3.10).

names = "Barry Lima Bab"

name = names.split(" ")
print(f"{name=}")  # name=['Barry', 'Lima', 'Bab']

num = len(name)
print(f"{num=}")  # num=3

ab = ""

print("Number of words:", num)

for i in range(num):
    print(name[i])  # Barry -> Lima -> Bab
    if name[i] == ' ':
        if name[i-1] == a:
            ab.append()   " "
        elif name[i-1] == b:
            ab.append()   " "

print(f"{ab=}")  # ab=''
a_b = ab.split(' ')
print(f"{a_b=}")  # a_b=['']

Breaking things down step by step like this is a great starting point for better understanding what's going on.

  1. if name[i] == ' ': Notice the value of name[i] so this check never resolves to True meaning the code inside never runs
  2. if the inner code did run, you'd hit a NameError: name 'a' is not defined. Did you mean: 'ab'? because a is undefined. Probably meant 'a' here. same for b
  3. In my example, name[i-1] would be 'Bab' -> 'Barry' -> 'Lima' which is probably not what you're expecting. This is because you're getting the -1th, 0th, 1st items in name. to get the last letter from the name, you want name[i][-1] here
  4. if you then get into either of the furthest inside conditions, you'd encounter AttributeError: 'str' object has no attribute 'append' which happens because append is for list not str. You couldchange ab to be a list to use this in which case you'd want ab.append(name[i]) or you can use string concatenation like ab = " " name[i] or using str.concat
  5. 1 last note of interest, you may have noticed your code as-is really likes to return and say that there's 1 item. This is because the above issues always (if the program doesn't break) leaves ab == '' and ''.split(' ') => [''] and thus len(ab.split(" ")) => 1

1 tip that I think would help in code comprehension is that the name variable here is not a single name string like it implies. It's actually a list[str]. I'd probably denote the variables something more like names_str: str vs names: list[str] or raw_names vs names. Then just use something like for name in names: and not worry about indexes. You can also use name.endswith('a') instead of name[-1] == 'a' for better readability.

Eventually you can combine these into a list comprehension for maximal succinctness -> len([name for name in names if name.endswith('a') or name.endswith('b')]).

CodePudding user response:

name[i-1] is the previous name in the list, not the last character of the current name in the loop.

There's no need to append the matching names to a string. If you just need the count of matches, increment a counter variable.

You need to put a and b in quotes to make them strings, not variables.

names = input("Enter list of names: ")
name = names.split(" ")

matches = 0

print("Number of words:", len(name))

for cur_name in name:
    if cur_name.endswith('a') or cur_name.endswith('b'):
        matches  = 1
    
print("Number of words that end with a or b: ", matches)

CodePudding user response:

Use the endswith string method to detect if the last letter is "a" or "b"

names = ["bob","boba","larry","curly","moe"]
count = 0
for name in names:
    if name.endswith("a") or name.endswith("b"):
        count  = 1
print(f"{count=}") # count=2
  • Related