Python: ejecución no deseada a través del bucle else/if not

CorePress2024-01-25  9

Este es un error pequeño pero crucial porque afecta el código donde tienes que dar un 'mensaje no encontrado' específico... pero el problema también podría radicar en el hecho de que estoy usando archivos csv. En este código especifiqué que "no encontrado" debe imprimirse solo si no se encuentra el registro, pero se sigue imprimiendo de todos modos.

CÓDIGO

import csv
with open('data.csv','w') as f:
    ans='y'
    while ans=='y':
        s=csv.writer(f)
        g=int(input("Enter GR number:"))
        n=input("Enter name:")
        m=float(input("Enter total marks:"))
        s.writerow([g,n,m])
        print()
        ans=input('Enter more?')
        
with open('data.csv','r') as f:
    print("SEARCHING FOR GR NUMBER")
    print()
    gr=int(input('Enter GR number to search:'))
    s=list(csv.reader(f))
    for i in s:
        if str(gr) in i:
            print(i)
    if str(gr) not in i:
        print('Record not found')

SALIDA

Enter GR number:234
Enter name:Mia
Enter total marks:80

Enter more?y
Enter GR number:456
Enter name:Mark
Enter total marks:80

Enter more?n
SEARCHING FOR GR NUMBER

Enter GR number to search:234
['234', 'Mia', '80.0']
Record not found

Incluso he probado otros métodos para imprimir no encontrado... pero de todos modos ocurre el mismo error jajaja. Cualquier ayuda se agradece. ¡Gracias!

Es porque después de que tu bucle for encuentra el recable, busca hasta el final de todos modos y, cuando termina, marca el registro encontrado. ¿Cuál supones que es el valor de i cuando se completa el bucle for?

- acechador

28 de marzo de 2021 a las 2:57

'i' "es el registro en forma de lista... pero el segundo if está fuera del bucle for

- Lois Mathew

28 de marzo de 2021 a las 2:59

Lo entiendo :) Estoy explicando por qué no funciona.

- acechador

28/03/2021 a las 13:40



------------------------------------

Este caso particular requiere la aparentemente extraña construcción for... else de Python. La rama else solo se elige si el bucle for no termina debido a una declaración de interrupción.

Prueba esto:

for i in csv.reader(f):
    if str(gr) in i:
        print(i)
        break
else:
    print('Record not found')

1

ohh, muchas gracias, el código funciona muy bien y además tiene sentido... pero, por supuesto, ahora no se pueden imprimir 2 registros o más, aunque está bien :)

- Lois Mathew

28 de marzo de 2021 a las 3:23



------------------------------------

Suponiendo que también desee imprimir varios registros con el mismo número de GR, intente esto:

found = False
for i in s:
    if str(gr) in i:
        print(i)
        found = True
if not found:
    print('Record not found')

En tu código, solo verificarías la última línea que se repitió :)

0



------------------------------------

En este escenario, el elemento i es un iterador del contenedor s. Como está utilizando una lista de Python, los elementos se ordenarán por inserción. Entonces i == 234 en la primera iteración e i == 456 en la segunda iteración. A continuación, comprueba si "234" no en "456": lo cual es cierto.

4

pero incluso si uso la instrucción else dentro del bucle for, todavía da el mismo error

- Lois Mathew

28 de marzo de 2021 a las 3:06

En lugar de if str(gr) not in i, que comprueba el estado de un iterador de un bucle salido (probablemente no es algo que quieras hacer), podrías hacerlo if str(gr) not in s, que imprimirá el error solo cuando un usuario no haya ingresado el número GR correspondiente.

-iandinwoodie

28 de marzo de 2021 a las 3:10

Tenga en cuenta que la sugerencia en mi comentario anterior debería resolver su problema con cambios mínimos, pero no es un enfoque óptimo ya que itera el list dos veces. Una solución más podría ser utilizar un valor booleano (por ejemplo, encontrado = Verdadero) para indicar cuándo se encuentra al menos un registro. Luego puede imprimir el error si no lo encuentra.

-iandinwoodie

28 de marzo de 2021 a las 3:13

@Durtal proporcionó una gran solución. Ni siquiera sabía que había una construcción for/else en Python. Elimina la necesidad de administrar un booleano encontrado mientras se logra el mismo comportamiento.

-iandinwoodie

28 de marzo de 2021 a las 3:16



------------------------------------

En realidad estás escribiendo el último bloque un poco mal.

if str(gr) not in i:
        print('Record not found')

El código anterior escrito por usted simplemente verifica si str(gr) no está presente en i y cuál se escribirá para cualquiera de las iteraciones, ya que creo que solo estará presente en una posición particular. Por lo tanto, no se encontró la impresión.

Aquí tienes una solución;

def check():
    for i in s:
        if str(gr) in i:
            print(i)
            return
    print('Record not found')

check()

Aquí solo estoy verificando la misma condición, pero si coincide, simplemente estoy saliendo de la función, por lo que no imprimo la última línea (es decir, no encontrada). Y si no cumple la condición if, pasará a la última línea.

1

Muchas gracias... ahora la primera parte funciona muy bien... pero cuando ingreso un grno que no está en el registro... imprime "registro no encontrado"; cuatro veces

- Lois Mathew

28 de marzo de 2021 a las 3:05

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare