Grud Grud
Grud Grud

Reputation: 25

How to convert complex lists into strings and back in Python 3.7?

I'm trying to save Python lists to a file and read them back again when I re-launch the program. The problem is my lists are complex: i.e. different amounts of tuples within tuples.

The best I could come up with is turning my list into a string initially (which works) but there's no way I can think of to revert the changes.

with open(filename, 'w') as f:
            f.write(str(objs))
            f.close()

This works but how do I return this to a list?

Just to clarify what my definition of a complex list is, here's an example:

[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 
0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), 
(1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 
2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 
0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

Upvotes: 2

Views: 218

Answers (2)

trsvchn
trsvchn

Reputation: 8981

As @snakecharmerb already mentioned you can use json or pickle. Here is an example:

Code:

my_list = [(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 
0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), 
(1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 
2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 
0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

import json

with open('my_list.json', 'w') as f:
    json.dump(my_list, f)

with open('my_list.json','r') as f:
    loaded_list = json.load(f)

print('Using json:')
print(loaded_list)

import pickle

with open('my_list.pkl', 'wb') as f:
    pickle.dump(my_list, f)

with open('my_list.pkl', 'rb') as f:
    loaded_list = pickle.load(f)

print('Using pickle:')
print(loaded_list)

Output:

Using json:
[[[[0.0, 0.0, 0.0], [1000.0, 0.0, 0.0], [0.0, 2.0, 0.0], [1000.0, 2.0, 0.0], [0.0, 0.0, 1000.0], [1000.0, 0.0, 1000.0], [0.0, 2.0, 1000.0], [1000.0, 2.0, 1000.0]], [[0, 2, 3, 1], [4, 6, 7, 5], [1, 3, 7, 5], [4, 6, 2, 0], [2, 6, 7, 3], [4, 0, 1, 5]], [[255, 0, 0], [255, 128, 0], [255, 255, 0], [255, 255, 255], [0, 0, 255], [0, 255, 0]]]]

Using pickle:
[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

As you can see json converts tuples to lists.

Upvotes: 3

Varun Chhangani
Varun Chhangani

Reputation: 11

str function will convert your complex list / nested lists and tuple to string Further, eval converts any string to an actual code snippet

However as mentioned by Taras Savchyn, eval can lead to SQL injections and more. So instead use ast.literal_eval

Hence:

>>>import ast

>>> mylist = [(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

>>> mylist
[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

>>> mystring = str(mylist)

>>> print(mystring)
'[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]'

>>> type(mystring)
<class 'str'>

>>> print(ast.literal_eval(mystring))
[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

>>> type(ast.literal_eval(mystring))
<class 'list'>

Hope this solves your problem. You can comment the answer to ask any further queries

Upvotes: 1

Related Questions