Проблема здесь в том, что ваша структура является трехмерной, но CSV-файлы лучше всего подходят для двумерных данных.Существует вторичная проблема, заключающаяся в том, что ваш внутренний уровень состоит из кортежей, но внешние уровни представляют собой списки.
Вы можете решить обе эти проблемы, рассматривая это как простой список списков общих объектов Python (т. Е.игнорируя тот факт, что кортежи определяют 3-е измерение).Затем вы можете использовать код, подобный следующему:
import csv, ast
# store some sample data
list1 = [[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (3, 1), (3, 2)]]
with open('file1.csv', 'w') as f:
w = csv.writer(f)
w.writerows(list1)
# read the sample data
with open('file1.csv', 'r') as f:
r = csv.reader(f)
list2 = [
[ast.literal_eval(t) for t in row]
for row in r
]
list2 == list1
# True
Обратите внимание, что самые внутренние объекты будут храниться как строковое представление кортежа.Затем, когда они считываются обратно, ast.literal_eval
преобразует их обратно в кортежи.
В качестве альтернативы, я бы настоятельно рекомендовал нормализовать представление данных, например, хранить одну (x, y) пару в каждой строке файла CSV.вместе с их координатами строки и столбца.Это можно сделать следующим образом:
import csv
# store some sample data
list1 = [[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (3, 1), (3, 2)]]
with open('file1.csv', 'w') as f:
w = csv.writer(f)
for i, row in enumerate(list1):
for j, (x, y) in enumerate(row):
w.writerow([i, j, x, y])
# read the sample data
with open('file1.csv', 'r') as f:
r = csv.reader(f)
raw_data = [[int(v) for v in row] for row in r]
# figure out how many rows and columns there are
height = max(i for i, j, x, y in raw_data) + 1
width = max(j for i, j, x, y in raw_data) + 1
# create an empty "array" of the right size
list2 = [[None] * width for r in range(height)]
# fill up the array
for i, j, x, y in raw_data:
list2[i][j] = (x, y)
list2 == list1
# True
В качестве другой альтернативы: звучит так, как будто у вас есть свободный выбор структуры файла, поскольку вам не нужно организовывать свой CSV каким-либо конкретным способом.В этом случае вам лучше использовать бинарный или json-файл вместо csv, поскольку csv плохо подходит для хранения структурированных переменных, подобных вашей.
pickle
намного проще, но создает двоичный файл:
import pickle
# store some sample data
list1 = [[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (3, 1), (3, 2)]]
with open('file1.p', 'wb') as f:
pickle.dump(list1, f)
# read the data back
with open('file1.p', 'rb') as f:
list2 = pickle.load(f)
list1 == list2
# True
json
создает более читаемый файл, но код выглядит сложнее.
import json
# store some sample data
list1 = [[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (3, 1), (3, 2)]]
with open('file1.json', 'w') as f:
json.dump(list1, f)
# read the data back
with open('file1.json', 'r') as f:
list2 = json.load(f)
# convert inner lists to tuples (json doesn't distinguish them)
list2 = [[tuple(t) for t in row] for row in list2]
list1 == list2
# True