Eliminación del elemento en la lista durante el bucle
Tengo el código de abajo. Estoy tratando de eliminar dos cadenas de listas. predict strings
y test strings
si uno de ellos ha sido encontrado en el otro. El problema es que tengo que dividir cada uno de ellos y comprobar si hay una "porción" de una cadena dentro de la otra. Si hay entonces solo digo que hay una coincidencia y luego eliminar ambas cadenas de la lista así que ya no están iterados.
ValueError: list.remove(x): x not in list
Pero tengo el error anterior y estoy suponiendo que esto es porque no puedo borrar la cadena de test_strings ya que está siendo iterado encima? ¿Hay alguna manera de hacerlo?
Gracias.
for test_string in test_strings[:]:
for predict_string in predict_strings[:]:
split_string = predict_string.split('/')
for string in split_string:
if (split_string in test_string):
no_matches = no_matches + 1
# Found match so remove both
test_strings.remove(test_string)
predict_strings.remove(predict_string)
Ejemplo de entrada:
test_strings = ['hello/there', 'what/is/up', 'yo/do/di/doodle', 'ding/dong/darn']
predict_strings =['hello/there/mister', 'interesting/what/that/is']
así que quiero que haya una coincidencia entre hola / alla y hola / alla / musgo y para que sean eliminados de la lista al hacer la próxima comparación.
Después de una iteración Espero que sea:
test_strings == ['what/is/up', 'yo/do/di/doodle', 'ding/dong/darn']
predict_strings == ['interesting/what/that/is']
Después de la segunda iteración espero que sea:
test_strings == ['yo/do/di/doodle', 'ding/dong/darn']
predict_strings == []
Pregunta hecha hace 7 años, 1 meses, 5 días - Por geekguru
4 Respuestas:
-
Usted nunca debe tratar de modificar un iterable mientras usted está iterando sobre él, que es todavía eficaz lo que usted está tratando de hacer. Hacer un
set
para hacer un seguimiento de sus fósforos, y luego eliminar esos elementos al final.Además, tu línea
for string in split_string:
no está haciendo nada. No estás usando la variablestring
. O elimina ese bucle, o cambia tu código para que estés usandostring
.Puede utilizar la asignación aumentada para aumentar el valor de
no_matches
.no_matches = 0 found_in_test = set() found_in_predict = set() for test_string in test_strings: test_set = set(test_string.split("/")) for predict_string in predict_strings: split_strings = set(predict_string.split("/")) if not split_strings.isdisjoint(test_set): no_matches += 1 found_in_test.add(test_string) found_in_predict.add(predict_string) for element in found_in_test: test_strings.remove(element) for element in found_in_predict: predict_strings.remove(element)
Respondida el Apr 11, 2017 a las 23:37 - por pixelpilot
Votos positivos: 0 | Votos negativos: 0 -
De su código parece probable que dos
split_string
s match the sametest_string
. La primera vez a través del bucle eliminatest_string
, la segunda vez trata de hacerlo pero no puede, ya que ya está eliminado!Puedes intentarlo.
break
ing fuera del interiorfor
bucle si encuentra una coincidencia, o usoany
en lugar de eso.for test_string, predict_string in itertools.product(test_strings[:], predict_strings[:]): if any(s in test_string for s in predict_string.split('/')): no_matches += 1 # isn't this counter-intuitive? test_strings.remove(test_string) predict_strings.remove(predict_string)
Respondida el Apr 11, 2017 a las 23:45 - por bytebard
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando se debe a que estás modificando las listas
test_strings
ypredict_strings
mientras las estás recorriendo con un buclefor
. Esto puede causar problemas ya que la longitud de la lista cambia a medida que eliminamos elementos de ella, lo cual puede romper el bucle.Para evitar este problema, puedes crear listas auxiliares para almacenar los elementos que deseas eliminar, y luego eliminar esos elementos después de finalizar el bucle.
Aquí te dejo una versión corregida de tu código:
python test_strings = ['hello/there', 'what/is/up', 'yo/do/di/doodle', 'ding/dong/darn'] predict_strings = ['hello/there/mister', 'interesting/what/that/is'] matches_to_remove = [] for test_string in test_strings[:]: for predict_string in predict_strings[:]: split_string = predict_string.split('/') for string in split_string: if string in test_string: no_matches = no_matches + 1
Encontrar coincidencia para ser eliminados después
matches_to_remove.append(test_string) matches_to_remove.append(predict_string)Eliminar los elementos coincidentes
for match in matches_to_remove: if match in test_strings: test_strings.remove(match) if match in predict_strings: predict_strings.remove(match)De esta manera, primero guardamos los elementos que deseamos eliminar en una lista auxiliar
matches_to_remove
, y luego eliminamos esos elementos después de que termina el bucle principal. Esto debería evitar el error que estabas experimentando.Respondida el Apr 12, 2017 a las 23:33 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Para eliminar un elemento de una lista mientras se recorre en Python, debes usar el método
pop(index)
en lugar deremove(element)
.Tu código modificado sería:
python for test_string in test_strings[:]: for predict_string in predict_strings[:]: split_string = predict_string.split('/') for string in split_string: if (split_string in test_string): no_matches = no_matches + 1
Encontrado una coincidencia, eliminar ambos
test_strings.pop(test_strings.index(test_string)) predict_strings.pop(predict_strings.index(predict_string))El método
pop(index)
elimina el elemento en el índice especificado y devuelve ese elemento. En este caso, usamosindex
para obtener el índice del elemento que queremos eliminar.También es importante tener en cuenta que estás modificando las listas
test_strings
ypredict_strings
mientras las recorres. Para evitar problemas, siempre debes hacer una copia de la lista antes de modificarla, como:python for test_string in test_strings[:]: for predict_string in predict_strings[:]: ...
Esto creará una copia de cada lista y te permitirá recorrer las copias sin modificar las listas originales.
Respondida el Apr 12, 2017 a las 23:46 - por Gemini
Votos positivos: 0 | Votos negativos: 0