Home > Software engineering >  TypeError: list indices must be integers or slices, not str - dealing with dataframes
TypeError: list indices must be integers or slices, not str - dealing with dataframes

Time:11-18

I'm having the error below with a project and looked for some explanation (like this page) and I get the cause of the error. But I couldn't figure out what might be the problem in this case.

Traceback (most recent call last):
  File "c:\Users\luisa.oliveira\Programs\VScode\dashboard-ecg-atualizado\app\views\dashboard.py", line 688, in n_protocolo_callback
    g1, quantidades = graficos(
  File "c:\Users\luisa.oliveira\Programs\VScode\dashboard-ecg-atualizado\app\views\dashboard.py", line 51, in graficos
    desejados = ids[ids["ID"] == numero]["Protocolo"]
TypeError: list indices must be integers or slices, not str

some background to line 688:

def n_protocolo_callback(data, laudos, idade, sexo, operacao, pagina, quais_graficos):

    idade = faixas_idades.get(idade)
    idade_inicial, idade_final = None, None
    sexo = sexos.get(sexo)
    if idade:
        idade_inicial, idade_final = idade
    ids = laudos

    dados.loc[:, "Data"] = pd.to_datetime(dados.loc[:, "Data"])
    # cria primeiro gráfico
    g1, quantidades = graficos(
        dados, ids, data, laudos, [idade_inicial, idade_final], sexo
    )

beginnig of func: graficos()

def graficos(dados, ids, data, laudos, idade, sexo):
    data_inicial, data_final = data
    idade_inicial, idade_final = idade
    figura = []
    n_laudos = [numeros_diagnosticos.get(laudo) for laudo in laudos]
    mostrar = []

    for i, (nome, numero) in enumerate(zip(laudos, n_laudos)):
        desejados = ids[ids["ID"] == numero]["Protocolo"]

Edit: "ids" is a csv with 2 columns (ID and Protocolo) that's read by pd.read_csv. "numero" is an integer and "nome" a string

I think the problem has to do with indexing ids with "ID", but I'm not sure if that's right or how to solve it

CodePudding user response:

Global variables can be accessed inside of functions as long as they are on the right side of an assignment:

# Global variable
x = 3

def fun():
   # assign value of global variable x to local variable y
   y = x

If, however you have a variable with the same name of a global variable on the left side of an assignment, you'll create a local variable inside your function:

# Global variable
x = 3

def fun():
   # Initialize local variable
   x = 5
   print(x)

print(x)  # prints 3
fun()     # prints 5
print(x)  # prints 3

fun() assigns a different value to x but it doesn't affect the global variable outside.

If you define a function, all parameters are of local scope. When you pass those arguments to a function, Python checks in the current scope for all variable names and only goes to the next scope if it doesn't find all variables.

# Global variabl
x = 3

def outer():
   def inner(x):
      print(x)
   inner(x)

outer()  # Prints 3

Try to avoid using global variables as they obfuscate your code. I removed the parts not affecting your outcome for this explanation:

import pandas as pd

# global variables
ids = pd.DataFrame({"ID":[1, 2, 3, 4, 5, 6], "Protocolo":[444, 555, 666, 777, 888, 999,]})

# Presumably some list as this caused your TypeError
laudos = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def n_protocolo_callback(laudos):
    # Initialize a local variable ids with values from laudos
    ids = laudos
    # Calling graficos with local variable of ids
    g1, quantidades = graficos(ids, laudos)


# Define local variable of ids in the scope of function graficos
def graficos(ids, laudos):
    n_laudos = [numeros_diagnosticos.get(laudo) for laudo in laudos]

    for i, (nome, numero) in enumerate(zip(laudos, n_laudos)):
        # Accessing local variable ids
        desejados = ids[ids["ID"] == numero]["Protocolo"]

# Calling n_protocolo_callback will cause a TypeError
# n_protocolo_callback(laudos)

The error is caused as you re-assigned ids with the values of laudos inside n_protocolo_callback and then passed the local variable to graficos.

When you use global variables you don't need to add them as parameter to your function.


The TypeError is caused as a list can't be indexed with a string. As the error message reads you can index either using integer or slices, i.e:

l = [555, 666, 777, 888, 999]

# Accessing first element using integer
print(l[0])  # prints 555

# Accessing first 3 elements using slice:
print(l[0:3])  # prints [555, 666, 777]
  • Related