Python 为什么这两种形式的迭代产生不同的结果?
第一段代码没有实现我需要的东西,而第二段代码实现了Python 为什么这两种形式的迭代产生不同的结果?,python,Python,第一段代码没有实现我需要的东西,而第二段代码实现了 这两段代码之间的区别是什么?因为字符串是不可变的: 值可以更改的对象称为可变对象;对象 值一旦创建就不可更改,称为不可变。(修订) 包含对对象的引用的不可变容器对象的值 可变对象可以在后者的值更改时更改;但是 容器仍然被认为是不可变的,因为 它所包含的对象无法更改。因此,不可变性不是必需的 严格来说,与具有不可更改的值相同,它更微妙。) 对象的易变性由其类型决定;例如, 数字、字符串和元组是不可变的,而字典和 列表是可变的 在第一个示例中,每
这两段代码之间的区别是什么?因为字符串是不可变的: 值可以更改的对象称为可变对象;对象 值一旦创建就不可更改,称为不可变。(修订) 包含对对象的引用的不可变容器对象的值 可变对象可以在后者的值更改时更改;但是 容器仍然被认为是不可变的,因为 它所包含的对象无法更改。因此,不可变性不是必需的 严格来说,与具有不可更改的值相同,它更微妙。) 对象的易变性由其类型决定;例如, 数字、字符串和元组是不可变的,而字典和 列表是可变的 在第一个示例中,每次将附加值连接到一个名为
x
的新变量时,都会创建一个新变量
然而,在第二个示例中,您只是简单地更改了
列表的同一索引处的值。Shorty:在第一个示例中,您没有更改列表值,在第二个示例中,您更改了列表值。
在第一个循环中修改x
,它实际上是列表项的副本,但不是该项,在第二个示例中,通过索引访问列表项来修改列表项。请参阅以获取有关可变和不可变类型的更多信息
但是,如果要在包含可变类型的列表上应用循环,则项目将由for
循环修改:
alist = ['1', '2', '3']
blist = alist[:]
for x in alist:
if not "@gmail.com" in alist:
x = x + "@gmail.com"
for x in range(len(blist)):
if not "@gmail.com" in blist[x]:
blist[x] = blist[x] + "@gmail.com"
您的第一个循环可以固定为:
alist = [['1'], ['2'], ['3']]
blist = [['1'], ['2'], ['3']]
for x in alist:
x.append("@gmail.com")
print alist
for x in range(len(blist)):
blist[x].append("@gmail.com")
print blist
或者更简洁地说:
for i, x in enumerate(alist):
if "@gmail.com" not in x:
alist[i] = x + "@gmail.com"
由于
中的如果该字符串在字符串中的任何位置将返回true,因此在上述两种情况下首选而不是x.endswith(@gmail.com”)
当您在代码的第一个版本中执行x=x+“@gmail.com”
时,您正在创建一个新值,并重新绑定名称x
,以引用它。这对alist
没有影响,即使前面的x
值来自于此
另一方面,如果执行blist[x]=blist[x]+“@gmail.com”
,则显式修改列表。您正在重新绑定blist[x]
以引用新值
注意,对于不同的列表内容,您可能已经能够使用“就地”修改使代码的第一个版本工作。但是字符串是不可变的,因此没有就地操作。但是,如果alist
包含可变项,如list
s,则类似x+=[“foo”]
的代码将适当地扩展内部列表。如果对象的类型支持,则+=
运算符将尝试执行就地添加(通过使用\uuuuu iadd\uuu
方法)。但是,对于不支持就地操作的类型,它与x=x+y
相同,这与您遇到的问题相同。您可以通过使用列表理解来避免此问题:[x-if'@gmail.com'in x-else'{}@gmail.com'。blist中x的格式(x)
谢谢!你的代码很适合我!我还向您学习了string.format()。再次感谢@我不确定我是否理解这与字符串不可变有什么关系。如果alist
是一个列表列表,OP的第一个循环仍然不起作用。是的,但OP希望更改x
的值会反过来更改列表元素,但即使x
最初是对alist
元素的引用(通过for
),它也会在循环中重新初始化。如果x
是可变的,我们可以使用类似x.set_value(x+“@gmail.com”)
的东西,但是因为它是不可变的,所以它们不能。好吧,对我来说,这似乎更多地与python迭代器的性质有关,而不是与iterable中对象的可变性有关。不过我知道你是从哪里来的。正如我所解释的,如果x
是另一个(可变)对象,那么无论Python迭代器的性质如何,这两个循环都可以编写为工作相同。而不是x.endwith(@gmail.com”)
非常棒!你的理解是错误的。它创建的列表将不包含以“@gmail.com”
开头的列表项。@pzp:谢谢--已修复
email="@gmail.com"
alist=[x+email if email not in x else x for x in alist]