В чем разница между «для меня в alist» и «для меня в диапазоне (len (alist))»? - PullRequest
0 голосов
/ 08 февраля 2020

Я пытался преобразовать тип всех элементов в списке:

class Dict1(dict):
    pass
class Dict2(dict):
    pass
def print_type(alist):
    for i in range(len(alist)):
        print(type(alist[i]))
l=[]
for i in range(3):
    l.append(Dict1())


for element in l:
    element=Dict2(element)
print_type(l)


for i in range(len(l)):
    l[i]=Dict2(l[i])
print_type(l)

вывод:

<class '__main__.Dict1'>
<class '__main__.Dict1'>
<class '__main__.Dict1'>
<class '__main__.Dict2'>
<class '__main__.Dict2'>
<class '__main__.Dict2'>

, когда я использую for element in l, тип элементов не будет однако, он может быть преобразован в Dict2. for i in range(len(l)) может сделать это.

Кто-нибудь может сказать мне причину этого?

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Создает список, содержащий 3 элемента типа Dict1:

l=[]
for i in range(3):
    l.append(Dict1())

Однако при запуске:

for element in l:
    element=Dict2(element)

... назначение element=Dict2(element) не измените содержимое самого l. Здесь вы просто создаете новый объект с именем element, основанный на содержимом объекта Dict1, но это не обновляет переменную element как such.

Таким образом:

print_type(l)

печатает исходное содержимое списка l, элементы которого равны Dict1, как назначено в первом l oop.

Второй l oop:

for i in range(len(l)):
    l[i]=Dict2(l[i])

фактически назначает / обновления один элемент списка l, проиндексированный с помощью i переменная, с фактическим Dict2 объектом. Список обновляется, поэтому вместо Dict1.

отображается объект Dict2.
1 голос
/ 08 февраля 2020

In

for element in l:
    element=Dict2(element)

element - это просто переменная, которая содержит элемент в списке. Его переназначение просто меняет то, на что смотрит element, а не то, что содержит элемент в l oop.

Это похоже на то, как a никогда не меняется здесь:

a = 1
element = a
element = 2

print(a, element)  # 1 2

Переназначение переменной не влияет на другой код, который просматривает тот же объект.

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

l[i]=Dict2(l[i])

На самом деле, по сути,

l.__setitem__(i, Dict2(l[i]))

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

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