Python: Read by file and implement in a list

1

I process my problem: I want to read a file in which some features are stored. The file to read has this structure such that:

  • First line: Number of total levels ... (20)

  • Line with the number of cars (8)

  • The following lines indicate the cars and their characteristics:

  • H132 (Information: This is a car, H- Horizontal 1,3 position in a matrix, 2 length
  • V112
  • ...
  • Until we get to the previous number of cars, we would later find ourselves with another level ... An example would be:

    Well, what I want is to make a list of size the total number of levels, 20 and therefore in each level a new list with the previous cars is stored. This is my current code:

     infile = open('niveles.txt', 'r')
     niv = 0
     h = 0
     nivel = []
     caracteristicas = []
     for line in infile:
         loncad = len(line)
     if loncad < 4: # Toma las cadenas , en este caso de numero de coches
             i = int(line)
             print (i)
             if i != 20:  # Si es distinto de 20 , numero de niveles
                 niv +=1 # Contador de niveles...
    
     else:
        if loncad > 4: # Para las cadenas del coche...
           caracteristicas.append(line).
        nivel [niv] =  caracteristicas # Aquí recibo el error de asignación....
    
    
    print (nivel)
    

    The problem is that I receive range error and I can not understand ...

     Error recibido :
    
     nivel [niv] =  caracteristicas
    
     IndexError: list assignment index out of range
    
        
    asked by oxsaulxo 22.03.2017 в 19:37
    source

    2 answers

    1

    The error is because you must initialize the list nivel at the beginning of everything to contain 20 lists where to store the cars of each level:

    nivel = [list() for _ in range(20)]
    

    There are many other things that can be simplified, following your idea we can get what you want with:

    nivel = [list() for _ in range(20)]
    with  open('niveles.txt', 'r') as infile:
        niv = -1
        for line in infile:
            if len(line) < 4:
                if int(line) != 20:
                    niv +=1 
            else:
                nivel[niv].append(line)
    print (nivel)
    

    Anyway you get too complicated (or I get too complicated, as seen XD), 4 lines are enough to do that and it is possible that it can be improved using regular expressions for example:

    with open('niveles.txt', 'r') as f:
        aux = [line.rstrip() for line in f][1:]
        cochesNivel = ((i, int(n)) for i, n in enumerate(aux) if n.isdigit())
        niveles = [aux[i[0]+1:i[0]+i[1]+1] for i in cochesNivel]
    
        print(niveles)
    
    • We use with to handle the file, this ensures that when the code is finished the file will be closed securely.

    • aux is a list that contains all the lines of the file minus the first one (in fact you do not need to specify 20 levels if each level is specified by the number of cars). With rstrip we eliminate the end of line of the chain, when reading cad line of txt we obtain a string as 'H232\n' , with this we obtain 'H232' which is what interests us.

    • cochesNivel is a generator that searches for all the lines that only contain digits using the isdigit() method (those are the ones that indicate the number of cars per level). Notice that we can create 2000 cars per level, it does not have to be a string of less than 4 letters. For each match, a tuple containing the index where that data is stored is stored (the number of cars per level).

    • niveles is the output list, use the cochesNivel data to properly start aux in each level. It is created using list comprehensions.

    • If you want to use the list of levels outside of with you just have to declare it just before:

      niveles= list()
      with open('niveles.txt', 'r') as f:
          aux = [line.rstrip() for line in f][1:]
          cochesNivel = ((i, int(n)) for i, n in enumerate(aux) if n.isdigit())
          niveles = [aux[i[0]+1:i[0]+i[1]+1] for i in cochesNivel]
      
      print(niveles)
      

    For a txt of the form:

      

    3
      8
      H232
      H113
      V513
      H143
      V442
      V352
      H552
      H562
      8
      H232
      H112
      V613
      V123
      V423
      V513
      V333
      V623
      3
      H232
      H113
      V513

    We get:

      

    [['H232', 'H113', 'V513', 'H143', 'V442', 'V352', 'H552', 'H562'], ['H232', 'H112', 'V613' , 'V123', 'V423', 'V513', 'V333', 'V623'], ['H232', 'H113', 'V513']]

    I think this is what you want. In this case we have 3 lists within the list niveles (one per level) and in each one we store the cars that are in that level.

        
    answered by 22.03.2017 / 21:55
    source
    0

    Instead of indexing features use append. For example:

    infile = open('niveles.txt', 'r')
    niv = 0
    h = 0
    nivel = []
    caracteristicas = []
    lines = infile.readlines()
    nivel.append(int(lines[0]))
    numero_de_autos = int(lines[1])
    print(numero_de_autos)
    for i in range(2,numero_de_autos+2):
        caracteristicas.append(lines[i])
    print(caracteristicas)
    nivel.append(caracteristicas)
    print(nivel)  
    
        
    answered by 22.03.2017 в 21:23