0

I have a file from which contains on every line the following: name of the file, length of the list, the actual list. Here is an example:

a.txt 3 [4,2,9]
b.txt 5 [1,6,5,2,8]
c.txt 7 [1,2,3,4,5,6,7]

and so on. I have managed to read everything until the list, but the list gets read as strings. For example, for the first one, the output is '[4,','3,','4]' and I want to have a normal list. This is the code I have so far, but it's just a simple reading from the file:

f = open('example.txt', 'r')
for eachLine in f:
    a = eachLine.strip().split()
    l = a[2]
print l
f.close()

I used l=a[2] but this doesn't store my entire list, it only stores the first element from it.

How can I store the list from the file into a list in python?

user1956185
  • 389
  • 4
  • 8
  • 16
  • You need to evaluate the list as python list for that you can use [ast.literal_eval](https://docs.python.org/2/library/ast.html#ast.literal_eval) – Kobi K Jun 25 '14 at 07:35
  • If you actually want to simplify and add flexibility you can use [pickle](https://docs.python.org/2/library/pickle.html) to serialize your data. Then loading your data is as simple as `pickle.load(f)`. You'll need to do some converting, and save all data as pickle instead of the current format. – msvalkon Jun 25 '14 at 07:38
  • Is there space between the elements of the list? Try `.split(maxsplit=2)`. – jonrsharpe Jun 25 '14 at 07:59

4 Answers4

2
with open('example.txt', 'r') as f:
    for eachLine in f:                                         
        a = eachLine.strip().split(" ",2)                           
        req_list = [int(x) for x in a[2].strip('[]').split(',')]  
        print req_list                                         

output:

[4, 2, 9]
[1, 6, 5, 2, 8]
[1, 2, 3, 4, 5, 6, 7]
Hamish
  • 579
  • 5
  • 20
Ashoka Lella
  • 6,631
  • 1
  • 30
  • 39
  • This would work, but `l=a[2]` does not store the entire list. I edited my question to include this fact. – user1956185 Jun 25 '14 at 07:41
  • @user1956190, I don't understand. I've tested this and it works – Ashoka Lella Jun 25 '14 at 07:48
  • The assignment `l=a[2]` returns only the first element from the list. For example `[4,`. It only reads the elements from the list one by one. – user1956185 Jun 25 '14 at 07:52
  • @user1956190, split() function splits on spaces. Since your list is comma separated and does not contain spaces a[2] should be a complete list – Ashoka Lella Jun 25 '14 at 08:05
  • My list does contain spaces and only now I noticed that I forgot to write the list with spaces in the question. – user1956185 Jun 25 '14 at 08:11
  • @user1956190, Check the edited answer which restricts the number of splits to two thus working even if space exists or not – Ashoka Lella Jun 25 '14 at 08:12
1

Solution without using eval.

with open('input.txt', 'r') as f:
    for eachLine in f:
        a = eachLine.strip().split()
        l = list(int(x) for x in a[2][1:-1].replace(',',""))
        print l

OUTPUT

[4, 2, 9]
[1, 6, 5, 2, 8]
[1, 2, 3, 4, 5, 6, 7]
DOSHI
  • 442
  • 2
  • 23
0

You could use the eval function like so:

with open('example.txt', 'r') as f:
    for eachLine in f:
        tokens = eachLine.strip().split()
        theLen = int(tokens[0])
        theList = eval(tokens[1])

Be careful using eval however. If you're reading data from an untrusted source, they could do nasty things by passing in a file with arbitrary python code in it.

If possible you should use a file format like json for reading/writing simple data structures to disk as these formats already have robust de/serialization to protect against such attacks.

Hamish
  • 579
  • 5
  • 20
  • 2
    Same as Jeff answer eval is not recommended since it can be unsafe look [here](http://stackoverflow.com/a/15197698/1982962) – Kobi K Jun 25 '14 at 07:34
  • 1
    Sure it can be unsafe, but sometimes these things exist within a safe environment and using eval is a perfectly viable option. Without context to the problem its hard to know. Ideally you'd be using json or some other already existing file format that has these problems solved. – Hamish Jun 25 '14 at 08:10
  • Yes, but since you lack of detail recommending `eval` is not the best way to answer this question. – Kobi K Jun 25 '14 at 08:42
-1

You can use eval:

eval('[4,3,4]')

returns the list [4,3,4]

Jeff Tsui
  • 1,266
  • 12
  • 20
  • 4
    This is not recommened, if any then you can use [ast.literal_eval()](http://stackoverflow.com/a/15197698/1982962) – Kobi K Jun 25 '14 at 07:33