Вопрос по Python о правилах переменной области - PullRequest
1 голос
/ 15 февраля 2011

Это исходный код для быстрой сортировки в Python, который я нашел в Википедии.

def pivot(v, left, right):
    i = left
    for j in range(left + 1, right + 1):
        if v[j] < v[left]:
            i += 1 # .. incrementa-se i
           v[i], v[j] = v[j], v[i]
    v[i], v[left] = v[left], v[i]
    return i

def qsort(v, left, right):
    if right > left:
        r = pivot(v, left, right)
        qsort(v, left, r - 1)
        qsort(v, r + 1, right)

a = [4,2,4,6,3,2,5,1,3]
qsort(a, 0, len(a)-1)
print a # prints [1, 2, 2, 3, 3, 4, 4, 5, 6]

Мой вопрос касается области действия.Когда я передаю a в качестве аргумента в приведенном выше примере, как функция qsort может изменить переменную a в глобальной области видимости, если это не так "называть "глобальным"?Я программировал на python в течение 1 года и недавно начал изучать C. Похоже, я путаюсь.спасибо

Ответы [ 4 ]

6 голосов
/ 15 февраля 2011

Он не перепривязывает a / v, он просто мутирует . Вам не нужно объявлять имя global, если вы изменяете объект, к которому он привязан.

2 голосов
/ 15 февраля 2011

В питоне a передается "псевдоним" (см. Комментарий Йохена ниже) Поэтому любые изменения в v будут отражены в a.

РЕДАКТИРОВАТЬ: я исправил свою формулировку благодаря комментариям ниже.

0 голосов
/ 04 марта 2011

Да, ответ rebind хороший. Возможно, вам будет интересно - с момента запуска C вы, возможно, захотите ознакомиться с терминами call-on-value и call-by-reference . Возможно, знание о них заранее защитит вас от неожиданностей:

void callByValue(int number) {
    number = number + 1;
}

void callByReference(int *pnumber) {
    *pnumber = *pnumber + 1;
}

void main() {
    int x = 5;
    callByValue(x);
    // here, x is still 5

    int y = 5;
    callByReference(*y);
    // here, y is now 6.
}

Как бы то ни было, также в C вы обнаружите, что параметры число и номер будут связывать с действительными переменными x и y из внешнего мира. В Python тот факт, что у вас есть список a = [4,2,4,6,3,2,5,1,3], позволит вам изменить его вне a на его внутреннее имя v. Точно так же, как pnumber разрешил вам это в C. Для сравнения, кортеж не был бы изменяемым и был бы скопирован, то есть a = (4,2,4,6,3,2,5,1,3) не работал бы. Как и в C, number - это просто копия из x - и поэтому x не изменяется снаружи.

Кстати, я советую вам пропустить C, но продолжайте и возьмите немного C ++. Некоторые вещи там просто приятнее. Например, вы можете сделать это здесь без *pnumber все время:

void callByReferenceCPlusPlus(int &number) {
    number = number + 1;
}

void main() {
   int z = 5;
   callByReferenceCPlusPlus(z);
   // hooray, z is 6!
}

Это может быть дело вкуса, но на самом деле это более просто, не думая постоянно о деталях указателя. На самом деле.

0 голосов
/ 15 февраля 2011

qsort получает ссылку на объект списка, который также связан с a.Внутри функции тот же объект связан с локальной переменной v, поэтому любые изменения, сделанные с помощью v, также влияют на a.

Подробнее об объектах, ссылках и переменных читайте.

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