Autor Tema: El porque del error . (PYTHON)

0 Usuarios y 1 Visitante están viendo este tema.

04 Enero, 2024, 11:27 pm
Leído 134 veces

napolitana

  • $$\Large \color{#6a84c0}\pi$$
  • Mensajes: 21
  • País: es
  • Karma: +0/-0
Hola a todos ,

Quería preguntarles , el motivo del error , que no lo entiendo . Siento mucho , si el programa aún muy simple o muy de principiante el error  :'( ( estoy empezando a programar  :)

En cuanto a la duda esquematización intento usar el método .join , pero nosé porque no me arranca . Me sale un TypeError: can only concatenate list (not "str") to list . En cambio si no utilizo el .join en la función y lo utilizo fuera de la función , cuando empieza a llamarlo , me va correcto . Querría poder entender porque no puedo usar el .join dentro de la función .

Muchas gracias




Código: [Seleccionar]
def inversa(a):
    lista = []
    for i in a:
        lista.append(i)
   
    if lista == []:
        return lista
    else:
        b = [lista[-1]] + inversa(lista[:-1])
   
    b2 = "".join(b)
    return b2

a = "palabra"
resultado = inversa(a)
print(resultado)


Como decía si no utilizo el .join dentro de la función y lo uso fuera , en la llamada no hay problema .
Código: [Seleccionar]

def inversa(a):
    lista = []
    for i in a:
        lista.append(i)
   
    if lista == []:
        return lista
    else:
        b = [lista[-1]] + inversa(lista[:-1])
   
    return b

a = "palabra"
print(inversa(a))
lista2=(inversa(a))
b2 = "".join(lista2)
print(b2)



Hay algún problema cuando aplico recursividad , y por eso me falla . Si es eso , tampoco logro entender el problema , si alguien me podría explicar . Y algún consejo para elaborar funciones .


05 Enero, 2024, 01:41 am
Respuesta #1

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,739
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Hola.

El problema no es el join, sino la concatenación.
En algún momento estás concatenando una lista con una string, y eso no está permitido.
Podrías poner un print en cada paso, para visualizar los resultados intermedios,
y tratar de entender dónde está el error de diseño.

Saludos.

05 Enero, 2024, 01:47 am
Respuesta #2

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,739
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Hay otra cosa que te puede ayudar en la lógica del problema.

Si bien Python no controla los tipos de datos de los argumentos y de los datos retornados por las funciones,
si uno tiene claro que quiere un determinado tipo de datos,
puede especificarlo, sin que esto afecte la ejecución del programa.

Son los "hints" que pueden agregarse a argumentos y retornos de funciones.
Para tu función, sería así:


def inversa(a:str) -> str:
    ...


Ahí he agregado indicaciones de que se espera un argumento de tipo string,
y se espera que la función retorne un string.

Con eso en mente, basta que verifiques si estás cumpliendo esas condiciones
en la lógica de tu programa.

(1) Cada vez que llames a la función, asegurarte de que el argumento que le estás pasando es de tipo string.

(2) En cada punto en que la función retorna (sentencia return) asegurarte de que realmente se retorna un string.

En ese caso, estoy viendo que dentro de tu función tenés un return que devuelve una lista vacía en algunos casos, en vez de una string vacía.
Eso seguro es fuente de errores en una llamada recursiva.



05 Enero, 2024, 11:23 am
Respuesta #3

DaniM

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 207
  • País: cz
  • Karma: +0/-0
Hola,

Como dice argentinator, fíjate que en esta línea:

Código: [Seleccionar]
[lista[-1]] + inversa(lista[:-1])
El primer término es una lista y el segundo es un string, y no puedes usar el operador + para dos tipos de datos distintos. O sumas dos strings o sumas dos listas.

Además, en el caso base:

Código: [Seleccionar]
if lista == []:
    return lista

Estás devolviendo una lista mientras que en los demás casos estás intentando devolver un string.

Haciendo los cambios mínimos para que tu código funcione quedaría así:

Código: [Seleccionar]
def inversa(a):
    lista = []
    for i in a:
        lista.append(i)
   
    if lista == []:
        return ""
    else:
        b = lista[-1] + inversa(lista[:-1])

    b2 = "".join(b)
    return b2

a = "palabra"
resultado = inversa(a)
print(resultado)

05 Enero, 2024, 11:36 am
Respuesta #4

DaniM

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 207
  • País: cz
  • Karma: +0/-0
Por cierto, una manera más directa de hacerlo por recursividad, para ahorrarte todo el proceso que haces con las listas, sería ésta:

Código: [Seleccionar]
def inversa (a):
    if (len (a) < 2):
        return a
    else:
        return a[len (a) - 1] + inversa (a[:len (a) - 1])

print (inversa ("palabra")) #arbalap

05 Enero, 2024, 12:45 pm
Respuesta #5

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,339
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Hola a todos ,

Quería preguntarles , el motivo del error , que no lo entiendo . Siento mucho , si el programa aún muy simple o muy de principiante el error  :'( ( estoy empezando a programar  :)

En cuanto a la duda esquematización intento usar el método .join , pero nosé porque no me arranca . Me sale un TypeError: can only concatenate list (not "str") to list . En cambio si no utilizo el .join en la función y lo utilizo fuera de la función , cuando empieza a llamarlo , me va correcto . Querría poder entender porque no puedo usar el .join dentro de la función .

Muchas gracias




Código: [Seleccionar]
def inversa(a):
    lista = []
    for i in a:
        lista.append(i)
   
    if lista == []:
        return lista
    else:
        b = [lista[-1]] + inversa(lista[:-1])
   
    b2 = "".join(b)
    return b2

a = "palabra"
resultado = inversa(a)
print(resultado)


Como decía si no utilizo el .join dentro de la función y lo uso fuera , en la llamada no hay problema .
Código: [Seleccionar]

def inversa(a):
    lista = []
    for i in a:
        lista.append(i)
   
    if lista == []:
        return lista
    else:
        b = [lista[-1]] + inversa(lista[:-1])
   
    return b

a = "palabra"
print(inversa(a))
lista2=(inversa(a))
b2 = "".join(lista2)
print(b2)



Hay algún problema cuando aplico recursividad , y por eso me falla . Si es eso , tampoco logro entender el problema , si alguien me podría explicar . Y algún consejo para elaborar funciones .

El error lo da al intentar usar la función con el join, mientras no lo intente no da error (prueba a cambiar “return b2” por “return b” y obtendrás el mismo resultado que en el segundo programa, sin error, porque usa la función sin el join; aunque esté definido en la función le da igual). Fíjate que en el segundo programa no imprime b2, te imprime solamente “inversa(a)”; no se queja, pero tampoco lo usa.

Por otra parte, el join es para convertir una lista así [“a”,”b”,”c”] (con caracteres alfanuméricos, o sea, entre comillas) en una string; pero si le das una string como “palabra”... ya esto hecho el join :) ya están unidas las letras sin comillas; el objetivo del join es ése. Ah, no, perdón, que hace el join a la inversa

Otra cosa más, pones b = [lista[-1]] + inversa(lista[:-1]), donde “inversa” es la función que se está ejecutando, y todavía en ese punto no has terminado de definir dicha función.

Saludos.

05 Enero, 2024, 01:40 pm
Respuesta #6

DaniM

  • $$\Large \color{#5e8d56}\pi\,\pi\,\pi$$
  • Mensajes: 207
  • País: cz
  • Karma: +0/-0
Otra cosa más, pones b = [lista[-1]] + inversa(lista[:-1]), donde “inversa” es la función que se está ejecutando, y todavía en ese punto no has terminado de definir dicha función.

Es cierto que podría haber hecho simplemente

Código: [Seleccionar]
return lista[-1] + inversa(lista[:-1])
y ahorrarse las dos siguientes líneas, pero de la otra manera también funciona porque a la hora de ejecutar el programa, lo que hace el intérprete por dentro es evaluar la cadena de llamadas a la función hacia atrás, es decir, primero hace inversa("") y devuelve "", luego vuelve a inversa("a"), asigna b = "a" + "", hace el join (que como dices, es innecesario) y devuelve "a", luego vuelve a inversa("ra"), asigna b = "r" + "a", hace el join y devuelve... y así hasta que llega a inversa("palabra"), es decir, que aunque ella llame la función dentro de sí misma antes de hacer el return final, a la hora de la ejecución lo que va después se sigue evaluando en cada llamada.

05 Enero, 2024, 01:43 pm
Respuesta #7

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,339
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Otra cosa más, pones b = [lista[-1]] + inversa(lista[:-1]), donde “inversa” es la función que se está ejecutando, y todavía en ese punto no has terminado de definir dicha función.

Es cierto que podría haber hecho simplemente

Código: [Seleccionar]
return lista[-1] + inversa(lista[:-1])
y ahorrarse las dos siguientes líneas, pero de la otra manera también funciona porque a la hora de ejecutar el programa, lo que hace el intérprete por dentro es evaluar la cadena de llamadas a la función hacia atrás, es decir, primero hace inversa("") y devuelve "", luego vuelve a inversa("a"), asigna b = "a" + "", hace el join (que como dices, es innecesario) y devuelve "a", luego vuelve a inversa("ra"), asigna b = "r" + "a", hace el join y devuelve... y así hasta que llega a inversa("palabra"), es decir, que aunque ella llame la función dentro de sí misma antes de hacer el return final, a la hora de la ejecución lo que va después se sigue evaluando en cada llamada.

Muchas gracias, Dani.
Es que hace bastante que no programo nada y además soy  aficionado, así que no te extrañes.

Saludos.