В чем разница между mylist и mylist [:]? [Дубликат]

Если мы рассмотрим общие сценарии, в которых может быть выбрано это исключение, доступ к свойствам с объектом вверху.

Пример:

string postalcode=Customer.Address.PostalCode; 
//if customer or address is null , this will through exeption

здесь, если адрес равен нулю, то вы получите NullReferenceException.

Итак, в качестве практики мы всегда должны использовать проверку нуля, прежде чем обращаться к свойствам в таких объектах (особенно в общих)

string postalcode=Customer?.Address?.PostalCode;
//if customer or address is null , this will return null, without through a exception
10
задан Matt Joiner 28 June 2011 в 03:19
поделиться

4 ответа

Я обсуждал это некоторое время, потому что подобные вопросы задавались много раз здесь. Но это просто уникально, чтобы получить преимущество от сомнений. (Тем не менее, я не буду возражать, если другие голосуют, чтобы закрыть.) Вот визуальное объяснение того, что происходит.

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]       <-  b = 0; remove? no
 ^
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]       <-  b = 1; remove? yes
    ^
[0, 2, 3, 4, 5, 6, 7, 8, 9]          <-  b = 3; remove? no
       ^
[0, 2, 3, 4, 5, 6, 7, 8, 9]          <-  b = 4; remove? yes
          ^
[0, 2, 3, 5, 6, 7, 8, 9]             <-  b = 6; remove? no
             ^
[0, 2, 3, 5, 6, 7, 8, 9]             <-  b = 7; remove? yes
                ^
[0, 2, 3, 5, 6, 8, 9]                <-  b = 9; remove? no
                   ^

Поскольку никто больше не имеет, я попытаюсь ответить на ваши другие вопросы:

Почему не указана ошибка, указывающая, что базовый итератор изменяется?

Чтобы выбросить ошибку, не запрещая многие совершенно правильные конструкции контуров, Python должен был знать lot о том, что происходит, и, вероятно, это должно было бы получить информацию во время выполнения. Вся эта информация потребует времени для обработки. Это сделало бы Python намного медленнее, только в том месте, где скорость действительно рассчитывается - цикл.

Изменились ли механики из более ранних версий Python в отношении этого поведения?

Короче говоря, нет. Или, по крайней мере, я сильно сомневаюсь в этом, и, конечно, он вел себя так, так как я узнал Python (2.4). Честно говоря, я бы ожидал, что любая простая реализация изменчивой последовательности будет вести себя именно таким образом. Любой, кто знает лучше, пожалуйста, поправьте меня. (На самом деле быстрый поиск документов подтверждает, что текст, указанный Mikola , приведен в учебнике с версии версии 1.4 !) [/ ​​G9]

14
ответ дан Community 25 August 2018 в 01:21
поделиться

На вашей первой итерации вы не удаляетесь и все денди.

Вторая итерация вы находитесь в позиции [1] последовательности, и вы удаляете «1». Итератор затем перенесет вас в позицию [2] в последовательности, которая теперь «3», поэтому «2» пропускается (поскольку «2» теперь находится в позиции [1] из-за удаления). Конечно, «3» не удаляется, поэтому вы переходите к позиции [3] в последовательности, которая теперь «4». Это удаляется, вы попадаете на позицию [5], которая теперь «6» и т. Д.

Тот факт, что вы удаляете вещи, означает, что позиция пропускается каждый раз, когда вы выполняете удаление .

0
ответ дан Justin Simon 25 August 2018 в 01:21
поделиться

Конечно, небезопасно изменять массив, когда вы выполняете итерацию по нему. Спектр говорит, что это плохая идея, и поведение не определено:

http://docs.python.org/tutorial/controlflow.html#for-statements

Итак, следующий вопрос: что именно происходит здесь под капотом? Если бы я должен был догадаться, я бы сказал, что он делает что-то вроде этого:

for(int i=0; i<len(array); ++i)
{
   do_loop_body(i);
}

Если вы полагаете, что это действительно то, что происходит, то это полностью объясняет наблюдаемое поведение. Когда вы удаляете элемент на или до текущего указателя, вы перемещаете весь список на 1 влево. В первый раз вы удаляете 1 - как обычно - но теперь список сдвигается назад. Следующая итерация вместо удара 2, вы нажмете 3. Затем вы удалите 4, и список сдвинется назад. Следующая итерация 7 и т. Д.

3
ответ дан Mikola 25 August 2018 в 01:21
поделиться

Как объяснил Микола, фактический результат, который вы наблюдаете, вызван тем фактом, что удаление записи из списка смещает весь список на одно место, заставляя вас пропускать элементы.

Но более интересный вопрос , на мой взгляд, почему python не выбирает для создания сообщения об ошибке, когда это происходит. Он вызывает такое сообщение об ошибке, если вы попытаетесь изменить словарь. Я думаю, для этого есть две причины.

  1. Dict сложны внутри, а списки - нет. Списки в основном представляют собой массивы. Дик должен обнаруживать, когда он изменен во время повторения, чтобы избежать сбоев при изменении внутренней структуры dict. Список может уйти, не выполняя эту проверку, потому что он просто убеждает, что его текущий индекс все еще находится в зоне действия.
  2. Исторически, (я не уверен сейчас), списки python были повторены с помощью []. Python будет оценивать список [0], список [1], список [2], пока не получит IndexError. В этом случае python не отслеживал размер списка до его начала, поэтому у него не было способа обнаружить, что размер списка был изменен.
4
ответ дан Winston Ewert 25 August 2018 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: