Python: вызов inner () из external () - PullRequest
0 голосов
/ 26 октября 2018

Я посмотрел вокруг на SO и неожиданно не нашел ответа на этот вопрос.Я предполагаю, что это потому, что обычно внутренние / вложенные функции используются для чего-то конкретного (например, для поддержания переменной среды, фабрики), а не для чего-то тривиального, как я пытаюсь использовать их.В любом случае, я не могу найти какую-либо информацию о том, как правильно вызывать внутреннюю функцию из внешней функции без необходимости декларировать inner() выше outer() в файле.Проблема из-за этой проблемы на HackerRank (https://www.hackerrank.com/challenges/circular-array-rotation/problem).

def circularArrayRotation(a, k, queries):

    def rotateArrayRightCircular(arr: list, iterations: int) -> list:
        """
        Perform a 'right circular rotation' on an array for number of iterations.
        Note: function actually moves last 'iterations' elements of array to front of array.

        >>>rotateArrayRightCircular([0,1,2], 1)
        [2,0,1]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
        [3,4,5,0,1,2]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
        [0,1,2,3,4,5]
        """
        return arr[-1 * iterations:] + arr[0:-1 * iterations]

    k = k % len(a)
    a = rotateArrayRightCircular(a, k)
    res = []
    for n in queries:
        res.append(a[n])
    return res

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

# trying 'self.inner()'
Traceback (most recent call last):
  File "solution.py", line 52, in <module>
    result = circularArrayRotation(a, k, queries)
  File "solution.py", line 13, in circularArrayRotation
    a = self.rotateArrayRightCircular(a, k)
NameError: name 'self' is not defined

# Removing 'self' and leaving the definition of inner() after the call to inner()
Traceback (most recent call last):
  File "solution.py", line 52, in <module>
    result = circularArrayRotation(a, k, queries)
  File "solution.py", line 13, in circularArrayRotation
    a = rotateArrayRightCircular(a, k)
UnboundLocalError: local variable 'rotateArrayRightCircular' referenced before assignment

Любая идея, как я мог бы включить def inner() после вызова inner() без выдачи ошибки?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Это невозможно в Python, но возможно в других языках, таких как Javascript и PHP.Это называется функцией подъема.

0 голосов
/ 26 октября 2018

Поскольку функция выполняется сверху вниз, и функция создается при обработке функции, то, что вы хотите, просто невозможно.

Вы можете поместить функцию перед внешней, сделав ее самой внешней, возможно добавив некоторые параметры (здесь не обязательно). (Кстати, это выглядит настолько обобщенно, что другие части кода, возможно, захотят использовать его, так почему бы не внешний?)

Но в противном случае вы застряли. По сути, это та же ситуация, что и в

def f():
    print(a) # a doesn't exist yet, so this is an error
    a = 4

Ну, вы могли бы сделать это так:

def circularArrayRotation(a, k, queries):

    def inner_code():
        k = k % len(a)
        a = rotateArrayRightCircular(a, k)

        # BTW, instead of the following, you could just do
        # return [a[n] for n in queries]
        res = []
        for n in queries:
            res.append(a[n])
        return res


    def rotateArrayRightCircular(arr: list, iterations: int) -> list:
        """
        Perform a 'right circular rotation' on an array for number of iterations.
        Note: function actually moves last 'iterations' elements of array to front of array.

        >>>rotateArrayRightCircular([0,1,2], 1)
        [2,0,1]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
        [3,4,5,0,1,2]

        >>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
        [0,1,2,3,4,5]
        """
        return arr[-1 * iterations:] + arr[0:-1 * iterations]

    return inner_code()

но я не вижу, чтобы вы от этого что-то выиграли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...