Обработка ошибок / исключений в цикле
У меня есть два соответствующих списка:
- Одним из них является список предметов
- Другой список этикеток для этих предметов
Я хочу написать функцию, которая проверяет, является ли каждый элемент в первом списке объектом JSON. Если это так, он должен оставаться в списке, но если нет, то он и соответствующая метка должны быть удалены.
Я написал следующий скрипт для этого:
import json
def check_json (list_of_items, list_of_labels):
for item in list_of items:
try:
json.loads(item)
break
except ValueError:
index_item = list_of_items.index(item)
list_of_labels.remove(index_item)
list_of_items.remove(index_item)
Однако он не удаляет элементы, которые не являются объектами JSON.
2 ответа
Решение
Не пытайтесь изменить список, который вы просматриваете; это ломает итератор. Вместо этого создавайте и возвращайте новые списки.
import json
def check_json (list_of_items, list_of_labels):
new_items = []
new_labels = []
for item, label in zip(list_of items, list_of_labels):
try:
json.loads(item)
except ValueError:
continue
new_items.append(item)
new_labels.append(label)
return new_items, new_labels
Если вы настаиваете на изменении исходных аргументов:
def check_json (list_of_items, list_of_labels):
new_items = []
new_labels = []
for item, label in zip(list_of items, list_of_labels):
try:
json.loads(item)
except ValueError:
continue
new_items.append(item)
new_labels.append(label)
list_of_items[:] = new_items
list_of_labels[:] = new_labels
но обратите внимание, что это на самом деле не более эффективно; он просто предоставляет другой интерфейс.
Вы можете создать список понимания и распаковать его:
def is_json(item):
try:
json.loads(item)
return True
except ValueError:
return False
temp = [(item, label) for item, label in zip(items, labels) if is_json(item)]
items, labels = zip(*temp)