Продолжение просто делает то, что предлагает его имя, оно немедленно продолжает следующее выполнение цикла без выполнения остальной части кода в цикле.
Итак, если у вас есть такой цикл:
int j=0;
int i = 0;
LABEL1 : for(;i < 3; i++){
if (true) {
continue;
}
someOtherMethod();
}
Часть someOtherMethod никогда не выполняется, потому что вы всегда будете нажимать на продолжение.
Причина, по которой ваш счетчик никогда не увеличивается, связан с метками, вы можете пометить цикл меткой (в вашем случае LABEL1
и LABEL2
и используйте эту метку, чтобы продолжить одну из внешних циклов вашего внутреннего цикла.
Таким образом, с вашим кодом цикл LABEL1
никогда не будет иметь шансов на увеличение его счетчик и, следовательно, i
остаются 0
, потому что ваш оператор продолжения немедленно продолжает следующую итерацию внешнего цикла.
Сообщаемое соотношение «скорость построения» справедливо только для константных кортежей (тех, элементы которых выражены литералами). Внимательно наблюдайте (и повторите на своем компьютере - вам просто нужно вводить команды в оболочке / командном окне!) ...:
$ python3.1 -mtimeit -s'x,y,z=1,2,3' '[x,y,z]'
1000000 loops, best of 3: 0.379 usec per loop
$ python3.1 -mtimeit '[1,2,3]'
1000000 loops, best of 3: 0.413 usec per loop
$ python3.1 -mtimeit -s'x,y,z=1,2,3' '(x,y,z)'
10000000 loops, best of 3: 0.174 usec per loop
$ python3.1 -mtimeit '(1,2,3)'
10000000 loops, best of 3: 0.0602 usec per loop
$ python2.6 -mtimeit -s'x,y,z=1,2,3' '[x,y,z]'
1000000 loops, best of 3: 0.352 usec per loop
$ python2.6 -mtimeit '[1,2,3]'
1000000 loops, best of 3: 0.358 usec per loop
$ python2.6 -mtimeit -s'x,y,z=1,2,3' '(x,y,z)'
10000000 loops, best of 3: 0.157 usec per loop
$ python2.6 -mtimeit '(1,2,3)'
10000000 loops, best of 3: 0.0527 usec per loop
Я не проводил измерения на 3.0, потому что, конечно, у меня его нет вокруг - он полностью устарел, и нет абсолютно никаких причин для его хранения, поскольку 3.1 превосходит его во всех отношениях (Python 2.7, если вы можете перейти на него, измеряется как почти на 20% быстрее, чем 2.6 в каждой задаче - - и 2.6, как вы видите, быстрее, чем 3.1 - так что, если вы серьезно заботитесь о производительности, Python 2.7 - действительно единственный выпуск, на который вы должны идти!).
В любом случае, ключевым моментом здесь является то, что в каждом выпуске Python построение списка из константных литералов происходит примерно с той же скоростью или немного медленнее, чем построение его из значений, на которые ссылаются переменные; но кортежи ведут себя по-разному - построение кортежа из константных литералов обычно в три раза быстрее, чем построение его из значений, на которые ссылаются переменные! Вы можете задаться вопросом, как это может быть, не так ли? -)
Ответ: компилятор Python может легко идентифицировать кортеж, составленный из константных литералов, как один неизменяемый константный литерал: так что он, по сути, строится только один раз, когда компилятор преобразует исходный код в байт-коды и хранит их в «таблице констант» соответствующей функции или модуля.Когда эти байт-коды выполняются, им просто нужно восстановить предварительно созданный постоянный кортеж - привет, престо! -)
Эту простую оптимизацию нельзя применить к спискам, потому что список является изменяемым объектом, поэтому очень важно, чтобы, если такое же выражение, как [1, 2, 3]
, выполняется дважды (в цикле - модуль timeit
выполняет цикл от вашего имени ;-), новый новый объект списка - конструируется каждый раз заново - и это построение (например, построение кортежа, когда компилятор не может тривиально идентифицировать его как постоянную времени компиляции и неизменяемый объект) действительно занимает некоторое время.
При этом конструкция кортежа (когда обе конструкции фактически должны происходят) по-прежнему примерно в два раза быстрее, чем построение списка - и это несоответствие может быть объяснено чистой простотой кортежа, о чем неоднократно упоминалось в других ответах. Но эта простота не учитывает ускорение в шесть или более раз, как вы заметите, если только сравните построение списков и кортежей с простыми константными литералами в качестве их элементов! _)
Благодаря мощности модуля timeit
вы часто можете самостоятельно решать вопросы, связанные с производительностью:
$ python2.6 -mtimeit -s 'a = tuple(range(10000))' 'for i in a: pass'
10000 loops, best of 3: 189 usec per loop
$ python2.6 -mtimeit -s 'a = list(range(10000))' 'for i in a: pass'
10000 loops, best of 3: 191 usec per loop
Это показывает, что кортеж незначительно быстрее, чем список для итераций. Я получаю аналогичные результаты для индексации, но для построения кортеж уничтожает список:
$ python2.6 -mtimeit '(1, 2, 3, 4)'
10000000 loops, best of 3: 0.0266 usec per loop
$ python2.6 -mtimeit '[1, 2, 3, 4]'
10000000 loops, best of 3: 0.163 usec per loop
Итак, если скорость итерации или индексации являются единственными факторами, фактически нет никакой разницы, но для построения кортежи выигрывают.
Алекс дал отличный ответ, но я попытаюсь остановиться на некоторых вещах, которые, на мой взгляд, заслуживают упоминания. Любые различия в производительности, как правило, небольшие и зависят от конкретной реализации: так что не делайте ставку на них.
В CPython кортежи хранятся в одном блоке памяти, поэтому создание нового кортежа включает в худшем случае один вызов для выделения памяти. Списки размещаются в двух блоках: фиксированном со всей информацией об объектах Python и блоком переменного размера для данных. Это одна из причин, по которым создание кортежа происходит быстрее, но, вероятно, это также объясняет небольшую разницу в скорости индексации, поскольку нужно следовать на один указатель меньше.
В CPython также есть оптимизация для уменьшения выделения памяти: объекты невыделенного списка сохраняются в свободном списке, поэтому их можно использовать повторно, но выделение непустого списка по-прежнему требует выделения памяти для данных. Кортежи сохраняются в 20 свободных списках для кортежей разного размера, поэтому выделение небольшого кортежа часто вообще не требует каких-либо вызовов выделения памяти.
Подобные оптимизации полезны на практике, но они также могут сделать рискованным слишком сильно зависеть от результатов timeit и, конечно, будут совершенно другими, если вы перейдете к чему-то вроде IronPython, где распределение памяти работает совершенно иначе.
По сути, потому что неизменяемость кортежа означает, что интерпретатор может использовать для него более компактную и быструю структуру данных по сравнению со списком.