0

I'm creating my first 'game' using pygame, and would like to add a load file option. The code I have is:

file = input('What save file should be opened? ')
file = file + '.txt'
file = open(file, 'r')
tilemap = file.read()

This works fine, until I get to this line

SCREEN.blit(textures[tilemap[row][column]], (column*TILESIZE, row*TILESIZE))

Where I get a KeyError: '['

This is because the file I open is a list of numbers, but it gets opened as a string - the program reads the '[' as part of a string. I've tried using:

tilemap = file.readlines()

But this gives a list with a string inside. Everything I've seen on the internet is putting strings or integers into a list, not just opening a list. How do I open a list??

EDIT:

The file (.txt) is a list of lists, such as:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
George Willcox
  • 677
  • 12
  • 30
  • Convert the strings to numbers... – Jongware Jan 31 '16 at 13:43
  • I'm guessing that your save file is just a list of integer numbers. Is that correct? `SCREEN.blit(textures[tilemap[row][column]], ...` is expecting a list of lists of numbers, so you need to convert your file data to that form. And to do that properly we need to know the **exact** format of your save file, so it would be _extremely_ useful if you could post a small representative sample of that file in your question. – PM 2Ring Jan 31 '16 at 13:47
  • Could you specify the exact format of the file? Is it the string representation of a Python list, e.g. "[1,2,3]" as a row? – Pachelbel Jan 31 '16 at 13:47
  • The file is a list of lists, such as: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] – George Willcox Jan 31 '16 at 13:56
  • `json.load`? `ast.literal_eval`? – GingerPlusPlus Jan 31 '16 at 14:02
  • Possible duplicate of [Reading a JSON file using Python](http://stackoverflow.com/questions/20199126/reading-a-json-file-using-python), [Parsing values from a JSON file in Python](http://stackoverflow.com/questions/2835559/parsing-values-from-a-json-file-in-python) – GingerPlusPlus Jan 31 '16 at 14:05
  • The file I'm reading from is .txt, not JSON – George Willcox Jan 31 '16 at 14:21

1 Answers1

2

As you discovered, somefile.read returns a string, one containing an expression. To turn the expression into the structure you want, you must evaluated it somehow. GingerPlusPlus gave two ways of doing so that is safer than using eval. To illustrate:

import ast, json

data ='[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'
for func in (ast.literal_eval, json.loads):
    ob = func(data)
    print(type(ob), ob)

prints

<class 'list'> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
<class 'list'> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

For more complicated expressions, the exact syntax of Python and Javascript (from whence comes JavaScript Object Notation) differ.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52
  • Could you please explain what happens here, I'm quite new and haven't worked with ast or json before. – George Willcox Jan 31 '16 at 14:56
  • 1
    Both, like `eval`, compile and execute the expression contained in a string to get some other Python object. `ast.literal_eval` us a restricted version of `eval`. After the expression is parsed to an ast (abstract syntax tree, read the doc), but before the ast is compiled, the ast is checked to make sure that the expression is a 'literal', in a generalized sense. No variables, only constants, and only safe operations with no side-effects. – Terry Jan Reedy Jan 31 '16 at 15:30