Это больше вопрос любопытства. Интересно узнать, можем ли мы вызвать функцию типа continue из значения словаря, чтобы пропустить итерацию

example_list = [1,2,3,4,5,6,7,8,9,10]

dict_function = { 3 : continue }

for val in example_list:
 dict_function[val]()
 print(val)

Ищете что-то вроде следующего для вывода

1
2
4
5
6
7
8
9
10

Возможно ли это?

0
user3166881 29 Авг 2017 в 01:59

3 ответа

Лучший ответ

continue это языковая конструкция, а не функция. Взгляните на разобранный байт-код:

import dis
dis.dis('for _ in range(5): continue')
  1           0 SETUP_LOOP              23 (to 26)
              3 LOAD_NAME                0 (range)
              6 LOAD_CONST               0 (5)
              9 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             12 GET_ITER
        >>   13 FOR_ITER                 9 (to 25)
             16 STORE_NAME               1 (_)
             19 JUMP_ABSOLUTE           13
             22 JUMP_ABSOLUTE           13
        >>   25 POP_BLOCK
        >>   26 LOAD_CONST               1 (None)
             29 RETURN_VALUE

Видите 19 JUMP_ABSOLUTE? Вот на что continue переводится на самом деле . Вы не можете «вызвать» его, как обычную функцию.


Попробуйте что-то вроде этого:

dict_function = { 3 : False }

for val in example_list:
    if not dict_function.get(val, True):
        continue

Используйте значение ключа, чтобы решить, пропустить ли эту итерацию или нет, а затем пропустить ее.

3
cs95 29 Авг 2017 в 03:54

Возможно ли это?

Нет. continue является синтаксической конструкцией. Заявление, это нельзя назвать. Он может использоваться только в контексте цикла. Использование в другом месте приведет к SyntaxError. Нет функции, которая могла бы копировать поведение continue, потому что это требует контекста окружающего цикла, как показывает ответ @ coldspeed.

Возможным обходным путем может быть установка флага. Если флаг имеет определенное значение, вы должны перейти:

example_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  
flags = {3 : True}

for val in example_list:
   if flags[val]:
       continue

Конечно, в приведенном выше решении предполагается, что у вас будет flags записей для всех других возможных значений в example_list. В противном случае вы получите KeyError.

2
Christian Dean 28 Авг 2017 в 23:12

Самая близкая вещь, которую я придумал, которая делает то, что вы хотите, это:

#!/usr/bin/env python3
# From:  https://stackoverflow.com/questions/45928441/how-to-call-continue-on-loop-from-within-dictionary-value


class Continue(Exception):  pass
def do_continue():  raise Continue


example_list = [1,2,3,4,5,6,7,8,9,10]

dict_function = {3:do_continue}

for val in example_list:
    try:
        if val in dict_function:
            dict_function[val]()
        print(val, end=' ')
    except Continue:  pass

Выход:

1 2 4 5 6 7 8 9 10

Вот что происходит:

  1. Мы определяем исключение Continue, единственной целью которого является перехват в конце цикла.
  2. Мы создаем функцию do_continue (), единственная цель которой - вызвать указанное исключение.
  3. Мы заполняем функцию dict_function ключом (3, do_continue), значение.
  4. Мы заключаем тело основного цикла в блок try / catch, ничего не делая, если перехватывается исключение Continue.
  5. В блоке try мы проверяем, существует ли val в dict_function, и, если это так, выполняем его.
2
J-L 28 Авг 2017 в 23:36