Home > database >  For Else anomaly
For Else anomaly

Time:05-25

I have a list called spanish containing loads of sentences, the objective is to input a word and print out all sentences containing that particular word.

My Code

word = input ("enter key word")
for span in spanish:
    if(word in span):
      print(span, '/n')
else:
     print("sorry that word in not in the list")

The Issue

If word is not in the list it works correctly. if word is in the list it prints all the qualifying sentences correctly but ALSO the else statement. It's doing my head in.

CodePudding user response:

See the Python documentation for the behavior of the else clause on loops.

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the iterable (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.

In your case, break is not an option because you want to print all sentences that match the keyword. For your purpose, you should use a flag that is set to True if any sentence contains the word. If not, we will print the error message at the end.

word = input ("enter key word")
found = False
for span in spanish:
    if word in span:
        print(span, end="\n\n")
        found = True
if not found:
     print("sorry that word is not in the list")

CodePudding user response:

Code example

#!/usr/bin/env python

spanish_data = [
    "Catedral",
    "Catedral Metropolitana de la Ciudad de México",
    "Hasta luego",
    "¿De dónde eres?",
]
matches = []

# Input
keyword = input("Enter keyword: ")

# Search
for needle in spanish_data:
    if keyword.lower() in needle.lower():  # e.g., match both Catedral terms
        matches.append(needle)

# Results
if len(matches):
    print(f'Matches for {keyword}: {", ".join(matches)}')
else:
    print(f"No matches for {keyword}")

Output

chmod x script.py, then ./script.py:

Enter keyword: Catedral
Matches for Catedral: Catedral, Catedral Metropolitana de la Ciudad de México
Enter keyword: México
Matches for México: Catedral Metropolitana de la Ciudad de México
Enter keyword: dónde
Matches for dónde: ¿De dónde eres?
Enter keyword: t
Matches for t: Catedral, Catedral Metropolitana de la Ciudad de México, Hasta luego
Enter keyword: no match
No matches for no match

Explanation: if x in s vs for-statements

for statement

The for loop will repeat (iterate) through each item in spanish_data. In your example, it printed multiple times since it'd go through the else block each time there was no match.

For more information see the for statement in Python's documentation.

When would you want to use a for statement? Here's a hypothetical example:

How does if keyword.lower() in needle.lower() work?

  • First is uses str.lower() to make the match case-insensitive. e.g. "MaTaMoRoS" is treated like "matamoros".

  • The in works with "México" in "Catedral Metropolitana de la Ciudad de México" since str is a sequence itself, from python docs:

    Strings are immutable sequences of Unicode code points.

    This means you can see if text exists in text, e.g. keyword in word, as well as keyword in list_items.

It's a lot to take in at once, but it doesn't contradict: Strings are nothing more than codepoints lumped together.

Bonus: if x in s

These types of statements are called membership testing.

Use an if keyword in spanish_data. This checks keyword (a string input) exists in the word Sequence type.

For more details, see Common sequence operations on python.org. For specifics, see lists, tuples, and ranges.

Further optimization: List comprehension

A list comprehension can be used here since the loop is simple enough. To try, replace the for loop:

for needle in spanish_data:
    if keyword.lower() in needle.lower():  # e.g., match both Catedral terms
        matches.append(needle)

With this list comprehension:

matches = [needle for needle in spanish_data if keyword.lower() in needle.lower()]

Analysis:

matches = [needle for needle in spanish_data if keyword.lower() in needle.lower()]
#            ^          ^            ^       ^
#            |          |            |       |
#            |          |            |        - Condition to filter with
#            |          |             --------- Sequence being iterated
#            |           ---------------------- Declares var in scope
#             --------------------------------- Item returned in iteration

CodePudding user response:

The issue here is that your ``èlseis executed in all the cases. You only want it to be executed if you've reached the end of the list and you haven't found your word in any of the sentences. Before you do execute your print that says not foundyou might want to add the condition reached the last sentence```:

for sentence in spanish:
  if word in sentence:
    print(sentence)
if sentence == spanish[-1] : # reached last sentence and didn't find the word in it 
  print('Not found')

CodePudding user response:

You could consider using a list comprehension to get all the matching sentences:

import unidecode

def normalize(sentence: str) -> str:
    """Returns string without accented characters for case-insensitive comparison."""
    return unidecode.unidecode(sentence.casefold())

def main() -> None:
    # From https://www.rosettastone.com/languages/spanish-words
    spanish_sentences = [
        'Buenos días',  #  Good morning
        'Buenas tardes',  #  Good afternoon
        'Buenas noches',  #  Good evening
        'Hola, me llamo Juan',  #  Hello, my name is John
        'Me llamo…',  #  My name is…
        '¿Cómo te llamas?',  #  What’s your name?
        'Mucho gusto',  #  Nice to meet you
        '¿Cómo estás?',  #  How are you?
        'Estoy bien, gracias',  #  I’m well thank you
        'Disculpa. ¿Dónde está el baño?',  #  Excuse me. Where is the bathroom?
        '¿Qué hora es?',  #  What time is it?
        '¿Cómo se dice ‘concert’ en español?',  #  How do you say ‘concert’ in Spanish?
        'Estoy perdido/a',  #  I am lost
        'Yo no comprendo',  #  I do not understand
        'Por favor, habla más despacio',  #  Would you speak slower, please
        'Te extraño',  #  I miss you
        'Te quiero',  #  I love you
    ]
    word = input('Enter key word: ')
    sentences_containing_word = [
        sentence for sentence in spanish_sentences
        if normalize(word) in normalize(sentence)  # Ideally you would want to store the normalized sentences so you don't need to normalize them each time you look up a word.
    ]
    if sentences_containing_word:
        print('\n'.join(sentences_containing_word))
    else:
        print('Sorry that word is not in the sentences list.')

if __name__ == '__main__':
    main()

Example Usage 1:

Enter key word: te
¿Cómo te llamas?
Te extraño
Te quiero

Example Usage 2:

Enter key word: como
¿Cómo te llamas?
¿Cómo estás?
¿Cómo se dice ‘concert’ en español?

Example Usage 3:

Enter key word: adios
Sorry that word is not in the sentences list
  • Related