Stack Exchange
Dictionary formation in python
I am trying to read a passage and make a dictionary out of the passage. The keys are the words and the values are the line numbers. The following is my code:   
import string
def build_word_index():
    input_file=(input('file name: '))
    input_file_open=open(input_file,'r')

    word_map = {}
    line_no = 0
    w=[]

    for line in input_file_open:

        word_lst = line.strip().split()

        word_lst = [w.lower().strip(string.punctuation) for w in word_lst]

        w.append(word_lst)           

        for word in w[line_no]:
            if word!="":
                word_map[word]=line_no
        line_no+=1

    print(word_map)

    index_lst = sorted(list(word_map.items()))
    print(index_lst)

    for word, line_set in index_lst:
        line_lst = sorted(list(line_set))
        line_str = str( line_lst[0] )
        for line_no in line_lst[1:]:
            line_str += ", {}".format( line_no )
        print("{:14s}:".format(word), line_str )



    input_file_open.close()

build_word_index()

The error that I am getting is:
ERROR:
Traceback (most recent call last):
  File "C:/Users/Dasinator/Documents/Books IX/Python Examples/textbook examples/lab10/lab10d.py", line 39, in <module>
    build_word_index()
  File "C:/Users/Dasinator/Documents/Books IX/Python Examples/textbook examples/lab10/lab10d.py", line 29, in build_word_index
    line_lst = sorted(list(line_set))
TypeError: 'int' object is not iterable

I was wondering, if someone could take a look at my codes and give me hints about fixing this error. Thanks

On what line does the error occur? That would help to localise your problem. If you found out the line error, you should use that information to create a MCVE.

Edited my question to include the complete error report. Hope it helps.

I see you have some print statements in your code. In particular, what is the output of the print(index_lst) in your run?

As I understand it, you want a list of lines for each word, not only the last line you encountered the word. If so, the word_map should be a map from words to lists of line numbers, not just to single numbers. Hence the line for adding a line number for a word is now word_map[word]+=[line_no]. The defaultdict was used instead of a simple dictionary to avoid writing the if word not in word_map: word_map[word] = [] part.
Here is a working version:
import string, collections
def build_word_index():
    input_file=(input('file name: '))
    input_file_open=open(input_file,'r')

    word_map = collections.defaultdict (list)
    line_no = 0
    w=[]

    for line in input_file_open:

        word_lst = line.strip().split()

        word_lst = [w.lower().strip(string.punctuation) for w in word_lst]

        w.append(word_lst)           

        for word in word_lst:
                word_map[word]+=[line_no]
        line_no+=1

    print(word_map)

    index_lst = sorted(list(word_map.items()))
    print(index_lst)

    for word, line_set in index_lst:
        line_lst = sorted(list(line_set))
        line_str = str( line_lst[0] )
        for line_no in line_lst[1:]:
            line_str += ", {}".format( line_no )
        print("{:14s}:".format(word), line_str )



    input_file_open.close()

build_word_index()

Example input:
one two
three three four
one two four
four three

Example output:
file name: defaultdict(<class 'list'>, {'one': [0, 2], 'three': [1, 1, 3], 'two': [0, 2], 'four': [1, 2, 3]})
[('four', [1, 2, 3]), ('one', [0, 2]), ('three', [1, 1, 3]), ('two', [0, 2])]
four          : 1, 2, 3
one           : 0, 2
three         : 1, 1, 3
two           : 0, 2


Your list index_lst is the product of a call to a dict's items method, which will give you a list of tuples containing its keys and values.
>>> d = {'a': 1, 'b': 2}
>>> d.items()
dict_items([('b', 2), ('a', 1)])

When you iterate over it the way you are, your first identifier names your current key and the second names the current value of your loop:
>>> for a, b in d.items():
...     print("a: {}, b: {}".format(a, b))
... 
a: b, b: 2
a: a, b: 1
>>> # Notice the keys are unsorted!

The next line of your loop, you try to pass your second identifier line_set to the list constructor, which makes a list out of anything that supports iteration.
line_lst = sorted(list(line_set))
# Hint: this is referenced in your error message

But line_lst is not an iterable object! It's just a normal integer (int), so Python gives up:
TypeError: 'int' object is not iterable


It has been answered, but here's my take on it.  Haven't tried the code, but I think it should work.
from collections import defaultdict
import re

def build_word_index(filename):
    word_index = defaultdict(list)

    with open(filename,'rb') as word_file:
        for i, line in enumerate(word_file):
            line = line.strip().lower()
            for word in line.split():
                word_index[word].append(i)

    for word in sorted(word_index):
        print word + ': ' + ', '.join(map(str,word_index[word]))

    return dict(word_index)


Appreciate your help. Thanks

You may want to watch this video by Raymond Hettinger. http://youtu.be/OSGv2VnC0go
