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 print
ed 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"
sincestr
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 askeyword 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