-5

Here is the question:

Write a function named wordPositions() with the following input and output. Input: s, a string consisting of upper and lower case letters and spaces. Return: a dictionary in which each distinct word in s is a key and the corresponding value is a list of the positions in s in which the word occurs. Words are to be treated as the same regardless of their capitalization. That is, "Yes" and "yes" are the same word. The following is an example of correct output.

s = 'One fish two fish red fish blue fish' 

wp = wordPositions(s) 

print(wp) 

{'two': [2], 'one': [0], 'red': [4], 'fish': [1, 3, 5, 7], 'blue': [6]}

Now here is my code:

def wordPositions(s):
aDict = {}
words = s.split(' ')
for item in words:
    position = words.index(item)
    aDict[item] = position
print(aDict)
print(wordPositions('One fish two fish red fish blue fish'))

The issue is my output:

{'two': 2, 'blue': 6, 'red': 4, 'fish': 1, 'One': 0}

How do I get it to look like the professor's? Also, notice how in my output, the word 'fish' shows only one position of it although it is repeated in the string. How do I get Python to show the multiple positions of 'fish'?

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Jorgan
  • 49
  • 3
  • 10
  • Your dictionary needs to hold lists. For this one you may want to look at `defaultdict` to allow your dictionary entries to be lists by default. The next thing is to iterate using `enumerate`. If you use index (without a `start` argument) it will keep finding the same index, not to mention that it will give your code `On^2` time complexity. Consider `for i, word in enumerate('One fish two fish red fish blue fish'.split()): print(i, word)` – Paul Rooney Dec 06 '16 at 04:57

4 Answers4

4

Each time you find a word's position and store it, you are overwriting the value for that key (if that word was found previously), not adding another value to it.

Don't assign the position values directly to a dictionary item. Instead, you need to assign an array to each dictionary item. Then you can push a new value onto the array each time you find a word's position.

First you need to check if the key already exists in the dictionary. If not, assign an empty array to that key first. Then (whether the key existed previously or not) push the new value onto the array (ie, the array that is the value for that key).

Edit: Also note that position = words.index(item) gets the position of the first occurrence of the item in word. So you need to make sure that the position of the word is not a duplicate (hint: use a for loop to do this).

(Apologies to @Cham K. who sent the above edit - I'm unsure how to automatically accept it.)

Edit 2 (as per @TigerhawkT3 comment): Use enumerate in your for loop. Makes it simpler to use in this case. (Google python enumerate).

Note: I'm deliberately not posting code here. Just (hopefully helpful) instructions. Looks like something you should be trying to figure out for yourself. :-)

Son of a Beach
  • 1,733
  • 1
  • 11
  • 29
  • 1
    I would also suggest recommending `enumerate`. – TigerhawkT3 Dec 06 '16 at 04:14
  • @TigerhawkT3 Yup. If each word in their string is always going to be separated by whitespace, that is the approach I'd take. – Christian Dean Dec 06 '16 at 04:15
  • 1
    I assume you're joking, and that you're not really asking other people to do your homework for you. Also see http://meta.stackexchange.com/questions/18242/what-is-the-policy-here-on-homework and http://meta.stackoverflow.com/questions/334822/how-do-i-ask-and-answer-homework-questions – Son of a Beach Dec 06 '16 at 04:42
  • 1
    @Jorgan If this thing is due at midnight, why didn't you do it earlier? – Right leg Dec 06 '16 at 04:47
  • 3
    @Jorgan not exactly gracious of the help, expecting others to do your work is not the purpose of SO. – AChampion Dec 06 '16 at 04:50
  • BTW, +1 for actually explaining instead of outputting code. – Right leg Dec 06 '16 at 04:53
0

Try this:

def wordPositions(s):
    aDict = {}
    words = s.split(' ')
    for item in words:
        aDict[item]=""
    for i in range(0,len(words)):
        if aDict[words[i]]=="":
            aDict[words[i]]=str(i)
        else:
            aDict[words[i]] = aDict[words[i]]+","+str(i)
    print(aDict)
wordPositions('One fish two fish red fish blue fish')
AChampion
  • 29,683
  • 4
  • 59
  • 75
Suman
  • 59
  • 1
  • 11
0

A Pythonic way could be the following dictionary comprehension:

def wordPositions(s):
    splitted = s.split()
    return {w: [i for i in range(len(splitted)) if splitted[i] == w]
                for w in set(splitted)}

As pointed out by BallpointBen in comments, this solution is not a good one from the complexity point of view, because it's a O(n^2) (one loop over the list embedded inside of a loop over the set).

Although, it might seem good, because it's a Pythonic solution which uses both dictionary and list comprehension.

The lesson to learn is, Pythonicity is good, but not everytime.

Right leg
  • 16,080
  • 7
  • 48
  • 81
0

your professor asks your to create a list of integer positions as the value of the dictionary however your method only put integer as the value. Hence the correct way is that to create a new list in the loop and keep appending to that if a new position is found.

Steve Deng Zishi
  • 128
  • 3
  • 10