Python while循环不断缩短我的列表!为什么?

Python while循环不断缩短我的列表!为什么?,python,while-loop,Python,While Loop,我有一个while循环,用于访问列表中的项目。我从不[故意]更改列表的内容,但在循环的每次迭代中,列表都会以某种方式缩短!我不知道为什么会发生这种情况,也不知道发生在哪里。由于这种缩短,我的“列表索引”变得超出范围,因为列表不再是其原始大小 为什么/在哪里发生这种情况 # email_to = { sw: [person1, email1, person2, email2, ..] } for sw, contacts in email_to.items(): number = len(

我有一个while循环,用于访问列表中的项目。我从不[故意]更改列表的内容,但在循环的每次迭代中,列表都会以某种方式缩短!我不知道为什么会发生这种情况,也不知道发生在哪里。由于这种缩短,我的“列表索引”变得超出范围,因为列表不再是其原始大小

为什么/在哪里发生这种情况

# email_to = { sw: [person1, email1, person2, email2, ..] }
for sw, contacts in email_to.items():
    number = len(contacts)
    number = number-1
    i = 0
    while i < number:
       print "All items in contacts: ", contacts  # <------- 'contacts' keeps getting shorter!!? WHY!?
       recipientName = contacts[i]
           if recipientName in contactsDict[sw]:
               print recipientName, "is a contact"
               affiliationType = "C"
           elif recipientName in developersDict[sw]:
               print recipientName, "is a developer"
           else:
               print recipientName, "is of unknown affiliation"
       recipientEmail = contacts[i+1]
       i += 2

       #If I remove this part below, the rest of the code works and the list is not altered ????
       other_recipients = email_to[sw]
       receiver = recipientName
       receiverIndex = other_recipients.index(receiver)
       receiverEmail = other_recipients[receiverIndex+1]
       if receiver in other_recipients:
           other_recipients.remove(receiver)
           other_recipients.remove(receiverEmail)
#email_to={sw:[person1,email1,person2,email2,…]}
对于sw,电子邮件_to.items()中的联系人:
编号=len(联系人)
数字=数字-1
i=0
而我<数字:

在评论下面的第一行打印“联系人中的所有项目:”,联系人#

 other_recipients = email_to[sw]
你不是在复制那个列表,你只是在引用它。这意味着调用
remove
也会影响原始列表。如果您打算将
其他收件人
作为发送给[sw]
电子邮件的副本,则必须明确复制该副本

other_recipients = list(email_to[sw]) # or email_to[sw][:]

一个简单的例子演示了这种行为

>>> a = [1,5,7]
>>> b = a
>>> b.append(99) #appends to b
>>> a # a now has 99 as well
[1, 5, 7, 99]
>>> a.remove(1) # removes from a
>>> b # b loses 1 as well
[5, 7, 99]
您可以使用
is
操作符来显示它们是相同的对象

>>> a is b
True
>>> c = list(a)
>>> c is a
False

在你评论下面的第一行

 other_recipients = email_to[sw]
你不是在复制那个列表,你只是在引用它。这意味着调用
remove
也会影响原始列表。如果您打算将
其他收件人
作为发送给[sw]
电子邮件的副本,则必须明确复制该副本

other_recipients = list(email_to[sw]) # or email_to[sw][:]

一个简单的例子演示了这种行为

>>> a = [1,5,7]
>>> b = a
>>> b.append(99) #appends to b
>>> a # a now has 99 as well
[1, 5, 7, 99]
>>> a.remove(1) # removes from a
>>> b # b loses 1 as well
[5, 7, 99]
您可以使用
is
操作符来显示它们是相同的对象

>>> a is b
True
>>> c = list(a)
>>> c is a
False

这不是你问题的答案,但为什么不在contacts中为recipientName使用
。我想我可以。我想我担心从列表中删除recipientName,所以我试着复制一份。但是,好建议,既然我知道我真正的错误在哪里,我可以把它删掉!这不是你问题的答案,但为什么不在contacts中为recipientName使用
。我想我可以。我想我担心从列表中删除recipientName,所以我试着复制一份。但是,好建议,既然我知道我真正的错误在哪里,我可以把它删掉!哇,我没意识到。非常感谢你!就像你说的,我以为我在复制。谢谢你帮我澄清一下@ryanhaining!我肯定是把它看作是一个副本而不是一个参考。@steph易变性是语言中为数不多的几个棘手的部分之一。一旦您意识到它遵循的是引用语义而不是值语义,就容易多了。即使类型是int
a=b
也只分配一个引用。然而,对于int,你不能对它们调用修改方法,
a=a+1
引用不同的int。非常感谢你!就像你说的,我以为我在复制。谢谢你帮我澄清一下@ryanhaining!我肯定是把它看作是一个副本而不是一个参考。@steph易变性是语言中为数不多的几个棘手的部分之一。一旦您意识到它遵循的是引用语义而不是值语义,就容易多了。即使类型是int
a=b
也只分配一个引用。但是,对于int,您不能对其调用修改方法,
a=a+1
引用不同的int。