Есть ли способ расширить итератор, перебирая его.

Я хочу перебрать запрос, и в случае истечения времени ожидания я хочу разделить запрос и добавить их в работающий цикл.

Что-то вроде этого:

l = [1, 2, 3, 4, 5]
it = iter(l)
for e in it:
  try: 
    request(e)
  except Exception:
    it.append(split_request(e))

Но append не работает, и itertools.chain возвращает новый итератор вместо его изменения на месте.

1
Querenker 2 Июл 2019 в 13:10

3 ответа

Лучший ответ

Вам нужен цикл while. Внутри этого, переберите список и соберите список неудачных записей. Когда этот список пуст, цикл while может завершиться. Что-то вроде:

while l:
    failures = []
    for e in l:
        try:
            request(e)
        except Exception:
            failures.append(split_request(e))
    l = failures

Должен сделать это.

2
holdenweb 2 Июл 2019 в 10:29

Приведенный ниже код дважды пробует каждый список и выводит словарь со значениями, которые привели к ошибкам и количеству попыток. Вы можете создать errors список и прекратить добавлять, если len(errors) слишком велик.

import itertools
l = [-2, -1, 0, 1, 'a', 2]
it = iter(l)
errors = {}
for e in itertools.chain(it, errors):
    try:
        print('e =', e, ' 1/e = ', end=' ')
        print(1/e)                              <---- May Fail 
    except Exception:
        errors[e] = errors.get(e, 0) + 1
        print('Error')

print('errors', errors)

O / P

e = -2  1/e =  -0.5
e = -1  1/e =  -1.0
e = 0  1/e =  Error
e = 1  1/e =  1.0
e = a  1/e =  Error
e = 2  1/e =  0.5
e = 0  1/e =  Error
e = a  1/e =  Error
>>> print('errors', errors)
errors {0: 2, 'a': 2}
1
Andrew Allen 2 Июл 2019 в 11:19

Вам просто нужен цикл while и обрабатывать индексацию и итерацию самостоятельно

l = [1, 2, 3, 4, 5]
i = 0
while i < len(l):
  try: 
    request(l[i])
    i += 1
  except Exception:
    l[i] = split_request(l[i])
1
Sayse 2 Июл 2019 в 11:12