1

So for my project I have to allow the user to input a sentence and then input a word and find all the occourunces of the word and print the numbers. Here's what I have

    found = 0

sen = input("Enter the sentence you would like to break down!")
sen1 = sen.upper()
list = sen1.split()


search=input("Enter the word you want to search")
search1 = search.upper()
for search1 in list:
    found = found + 1

position=list.index(search1)



if position == 0:
    print("First word in the sentence")
if position == 1:
    print("Second word in the sentence")
if position == 2:
    print("Third word in the sentence")
if position == 3:
    print("Fourth word in the sentence")
if position == 4:
    print("Fifth word in the sentence")
if position == 5:
    print("6th word in the sentence")

else:
    position1 = position + 1
    print(position1, "th word in the sentence")

but it only prints the first occurunce of the word and rarely works. Any solutions?

A. Stanley
  • 19
  • 1
  • 2
  • 2
    Just a comment, you shouldn't use the variable name `list` as it is a reserved word in python. You're replacing the functionality of default functions in python with your own variables and that can lead to unintended results. You can see the [full list here](https://docs.python.org/3.5/library/functions.html). – zephyr Mar 24 '16 at 14:25
  • `list` is a reserved keyword in python and shouldn't be used as a variable name. – jDo Mar 24 '16 at 14:27
  • `for loop` and `enumerate()` is what you are looking for probably. – Lafexlos Mar 24 '16 at 14:29
  • [How to find all occurrences of an element in a list?](http://stackoverflow.com/questions/6294179/how-to-find-all-occurrences-of-an-element-in-a-list) and [How to find all occurrences of an element in a list?](http://stackoverflow.com/questions/13478974/how-to-find-all-occurrences-of-an-element-in-a-list) – Lafexlos Mar 24 '16 at 14:30
  • @zephyr: `list` isn't exactly a reserved word, otherwise you'd get a SyntaxError when you try to redefine it. (See what happens if you try to assign to `for`, `in`, or `with`). But yes, one _should_ avoid shadowing the built-in names like `list`, `str`, `dict`, etc. – PM 2Ring Mar 24 '16 at 15:06

3 Answers3

2

Replace list with a_list.

List of positions of a search1 occurances:

positions = [idx for idx, el in enumerate(a_list) if el == search1]
Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
0

You have a great alternative which is re.finditer:

import re
sen = input("Enter the sentence you would like to break down!")
search = input("Enter the word you want to search")
for match in re.finditer(search, sen):
    print (match.start())
Idos
  • 15,053
  • 14
  • 60
  • 75
  • 2
    My guess is that this is a homework assignment and they're not supposed to use built in functions to accomplish the task. – zephyr Mar 24 '16 at 14:32
  • this prints the values of where the end of the word is, not the identified word – A. Stanley Mar 24 '16 at 14:33
  • OP asks for an alternative so I provided what is arguably the best one (: – Idos Mar 24 '16 at 14:34
  • @zephyr Don't you mean *only* use built-in functions? – jDo Mar 24 '16 at 14:42
  • 1
    Yes I suppose built-in would refer to native python functions whereas `re` functions wouldn't count as built-in. Terminology aside, they probably aren't meant to use `re`. – zephyr Mar 24 '16 at 14:45
0

Several comments have mentioned the danger of using list as a variable name. It's not actually a reserved word, but it is the name of a built-in type, and shadowing it by using it as a variable name can lead to mysterious bugs if you later wish to use this type to construct a list or test the type of an object.

A major problem with the code you posted is here:

search1 = search.upper()
for search1 in list:

The first line saves the upper-case version of the string search to the name search1. But the next line simply clobbers that with the words in list; it does not perform any searching operation. At the end of the for loop, search1 will be equal to the last item in list, and that's why your code isn't doing what you expect it to when it executes position=list.index(search1): you're telling it to find the position of the last word in list.


You could use .index to do what you want. To find multiple occurences you need to use a loop and pass .index a starting position. Eg,

def find_all(wordlist, word):
    result = []
    i = 0
    while True:
        try:
            i = wordlist.index(word, i) + 1
            result.append(i)
        except ValueError:
            return result

However, there's really not much benefit in using .index here..index performs its scan at C speed, so it's faster than scanning in a Python loop but you probably won't notice much of a speed difference unless the list you're scanning is large.

The simpler approach is as given in Tomasz's answer. Here's a variation I wrote while Tomasz was writing his answer.

def ordinal(n):
    k = n % 10
    return "%d%s" % (n, "tsnrhtdd"[(n // 10 % 10 != 1) * (k < 4) * k::4])

def find_all(wordlist, word):
    return [i for i, s in enumerate(wordlist, 1) if s == word]

sen = 'this has this like this'
wordlist = sen.upper().split()

words = 'this has that like'
for word in words.split():
    pos = find_all(wordlist, word.upper())
    if pos:
        pos = ', '.join([ordinal(u) for u in pos])
    else:
        pos = 'Not found'
    print('{0}: {1}'.format(word, pos))

output

this: 1st, 3rd, 5th
has: 2nd
that: Not found
like: 4th      

The code for ordinal was "borrowed" from this answer.

Community
  • 1
  • 1
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182