PYTHON: How to take a .txt file as input from user using raw_input in Python and then read that file row wise?
Question: I want to take a .txt file as input from user through `raw_input`.

Once the input is taken, I want the txt file name given by user to be accessed
and the contents from it written into another file (each in next row).

I am having a problem with how to connect a and b above or how to link raw
input with reading of file. I need help...the code is as follows (but it is
erroneous :S).

    
    
    import sys,os,csv
    
    x = raw_input("Enter name of file to be written row wise:")
    ui = "x" + txt
    for ui in x:
        data = open("ui").readlines()
        outfile = open("myfile.csv","w")
        out = csv.writer(outfile)
    for row in data:
        row = row.strip().split(';')
        if row:
            for subrow in row:
                subrow = subrow.strip().split()
                if subrow:
                    out.writerow(subrow)
    outfile.close()
    

I get the error:

> cannot concatenate 'str' and 'list' objects


Answer: 
    for row in data: 
        row = row.strip().split(';')
    

The fact that you perform `split(';')` has for consequence that a row (you
should write: line) split according to ';' gives always a not empty list, even
if it is an empty line, and even after having been stripped with **strip()** :
`''.split(';')` gives `['']` . So your following condition `if row:` is
useless.

That means that your code is equivalent to:

    
    
    for row in data:
        row = row.strip().split(';')
        for subrow in row:
            subrow = subrow.split()
            if subrow:
                out.writerow(subrow)
    

and then to:

    
    
    for row in data:
        for subrow in  row.strip().split(';'):
            subrow = subrow.split()
            if subrow:
                out.writerow(subrow)
    

.

Moreover , the fact that you use **split()** on **subrow** present in the list
**row.strip().split(';')** eliminates all the blanks before and after each of
the words present in **subrow**. So the first `strip()` in
`row.strip().split(';')` is useless too.

Your code is then equivalent to:

    
    
    for row in data:
        for subrow in row.split(';'):
            subrow = subrow.split()
            if subrow:
                out.writerow(subrow)
    

Now , `subrow.split()` can produce a void list when subrow is only blanks,
because `split()` without argument has its special algorithm. So the
instruction `if subrow` is usefull.

.

In fact, what your code does is, after having read the content of such a file:

    
    
    Blackcurrant, Redcurrant   ;  Orange ; Blueberry
        Pear;Chestnut;     Lemon Lime, Grapefruit
    Apple;Apricot   ;  Pineapple, Fig; Mulberry, Hedge Apple
    

to record another file like that:

    
    
    Blackcurrant
    Redcurrant
    Orange
    Blueberry
    Pear
    Chestnut
    Lemon Lime
    Grapefruit
    Apple
    Apricot
    Pineapple
    Fig
    Mulberry
    Hedge
    Apple
    

I prefer the following code to do that:

    
    
    filename = raw_input("Enter name of file to be written row wise:") + '.txt'
    filepath = 'I:\\' + filename
    
    with open(filepath) as handler,open("myfile.csv","wb") as outfile:
        out = csv.writer(outfile)
        for row in handler:
            gen = ( subrow.split() for subrow in row.split(';') )
            out.writerow([x for x in gen if x])
        del out
    

.

This code will always run, even for files extremely huge whose content can't
be held by the memory, because the lines of the file are read one after the
other.

In case the file isn't enormous like that, it is possible to proceed like you
did, with **readlines()** :

    
    
    with open(filepath) as handler:
        data = handler.readlines()
    
    with open("myfile.csv","wb") as outfile:
        out = csv.writer(outfile)
        for row in data:
            gen = ( subrow.split() for subrow in row.split(';') )
            out.writerow([x for x in gen if x])
        del out
    

But there is no particular interest to proceed so, you can do `for row in
handler` as well.

.

Personnaly, I think it would be better to use writerows():

    
    
    filename = raw_input("Enter name of file to be written row wise:") + '.txt'
    filepath = 'I:\\' + filename
    
    with open(filepath) as handler,open("myfile.csv","wb") as outfile:
        out = csv.writer(outfile)
        gen = ( x for row in handler for x in (subrow.split() for subrow in row.split(';')) )
        out.writerows([x for x in gen if])
        del out
    

.

I end this answer by informing you that a code employing a regex would be far
more efficient:

    
    
    import csv, re
    
    regx = re.compile('[ ;\r\n]+')
    
    filename = raw_input("Enter name of file to be written row wise:") + '.txt'
    filepath = 'I:\\' + filename
    
    with open(filepath) as handler,open("myfile.txt","w") as outfile:
        outfile.write('\n'.join(x for x in regx.split(handler.read()) if x))
    

## Edit 1

    
    
    handler = open(filepath)
    outfile = open("myfile.txt","wb")
    out = csv.writer(outfile)
    for row in handler:
        gen = ( subrow.split() for subrow in row.split(';') )
        out.writerow([x for x in gen if x])
    del out
    outfile.close()
    handler.close()
    

or

    
    
    import csv, re
    regx = re.compile('[ ;\r\n]+')
    filename = raw_input("Enter name of file to be written row wise:") + '.txt'
    filepath = 'I:\\' + filename
    
    handler = open(filepath)
    outfile = open("myfile.txt","w") 
    outfile.write('\n'.join(x for x in regx.split(handler.read()) if x))
    outfile.close()
    handler.close()
    

