Kevin
Kevin

Reputation: 716

Change string list to list

So, I saved a list to a file as a string. In particular, I did:

f = open('myfile.txt','w')
f.write(str(mylist))
f.close()

But, later when I open this file again, take the (string-ified) list, and want to change it back to a list, what happens is something along these lines:

>>> list('[1,2,3]')
['[', '1', ',', '2', ',', '3', ']']

Could I make it so that I got the list [1,2,3] from the file?

Upvotes: 5

Views: 1153

Answers (5)

unutbu
unutbu

Reputation: 879591

In [285]: import ast

In [286]: ast.literal_eval('[1,2,3]')
Out[286]: [1, 2, 3]

Use ast.literal_eval instead of eval whenever possible: ast.literal_eval:

Safely evaluate[s] an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

Edit: Also, consider using json. json.loads operates on a different string format, but is generally faster than ast.literal_eval. (So if you use json.load, be sure to save your data using json.dump.) Moreover, the JSON format is language-independent.

Upvotes: 3

sredmond
sredmond

Reputation: 460

I would write python objects to file using the built-in json encoding or, if you don't like json, with pickle and cpickle. Both allow for easy deserialization and serialization of data. I'm on my phone but when I get home I'll upload sample code.

EDIT: Ok, get ready for a ton of Python code, and some opinions...

JSON

Python has builtin support for JSON, or JavaScript Object Notation, a lightweight data interchange format. JSON supports Python's basic data types, such as dictionaries (which JSON calls objects: basically just key-value pairs, and lists: comma-separated values encapsulated by [ and ]. For more information on JSON, see this resource. Now to the code:

import json #Don't forget to import
my_list = [1,2,"blue",["sub","list",5]]
with open('/path/to/file/', 'w') as f:
  string_to_write = json.dumps(my_list) #Dump the string
  f.write(string_to_write)
  #The character string [1,2,"blue",["sub","list",5]] is written to the file

Note that the with statement will close the file automatically when the block finishes executing.

To load the string back, use

with open('/path/to/file/', 'r') as f:
  string_from_file = f.read()
 mylist = json.loads(string_from_file) #Load the string
  #my_list is now the Python object [1,2,"blue",["sub","list",5]]

I like JSON. Use JSON unless you really, really have a good reason for not.

CPICKLE

Another method for serializing Python data to a file is called pickling, in which we write more than we 'need' to a file so that we have some meta-information about how the characters in the file relate to Python objects. There is a builtin pickle class, but we'll use cpickle, because it is implemented in C and is much, much faster than pickle (about 100X but I don't have a citation for that number). The dumping code then becomes

import cpickle #Don't forget to import
with open('/path/to/file/', 'w') as f:
  string_to_write = cpickle.dumps(my_list) #Dump the string
  f.write(string_to_write)
  #A very weird character string is written to the file, but it does contain the contents of our list

To load, use

with open('/path/to/file/', 'r') as f:
  string_from_file = f.read()
  mylist = cpickle.loads(string_from_file) #Load the string
  #my_list is now the Python object [1,2,"blue",["sub","list",5]]

Comparison

Note the similarities between the code we wrote using JSON and the code we wrote using cpickle. In fact, the only major difference between the two methods is what text (which characters) gets actually written to the file. I believe JSON is faster and more space-efficient than cpickle - but cpickle is a valid alternative. Also, JSON format is much more universal than cpickle's weird syntax.

A note on eval

Please don't use eval() haphazardly. It seems like you're relatively new to Python, and eval can be a risky function to jump right into. It allows for the unchecked evaluation of any Python code, and as such can be a) risky, if you ever are relying on the user to input text, and b) can lead to sloppy, non-Pythonic code.

That last point is just my two cents.

tl:dr; Use JSON to dump and load Python objects to file

Upvotes: 1

aIKid
aIKid

Reputation: 28292

There are two easiest major options here. First, using ast.literal_eval:

>>> import ast
>>> ast.literal_eval('[1,2,3]')
[1, 2, 3]

Unlike eval, this is safer since it will only evaluate python literals, such as lists, dictionaries, NoneTypes, strings, etc. This would throw an error if we use a code inside.

Second, make use of the json module, using json.loads:

>>> import json
>>> json.loads('[1,2,3]')
[1, 2, 3]

A great advantage of using json is that it's cross-platform, and you can also write to file easily.

with open('data.txt', 'w') as f:
    json.dump([1, 2, 3], f)

Upvotes: 4

Jacob Budin
Jacob Budin

Reputation: 10003

Python developers traditionally use pickle to serialize their data and write it to a file.

You could do so like so:

import pickle
mylist = [1,2,3]
f = open('myfile', 'wb')
pickle.dump(mylist, f)

And then reopen like so:

import pickle
f = open('myfile', 'rb')
mylist = pickle.load(f) # [1,2,3]

Upvotes: 1

sashkello
sashkello

Reputation: 17871

  1. Write to file without brackets: f.write(str(mylist)[1:-1])

  2. After reading the line, split it to get a list: data = line.split(',')

  3. To convert to integers: data = map(int, data)

Upvotes: 0

Related Questions