Python为什么要使用[:] over =

时间:2013-01-21 06:59:57

标签: python python-3.x

我正在学习python,我正在学习https://developers.google.com/edu/python/strings

上的教程

字符串切片部分

  

s [:]是'你好' - 省略两者总能给我们一份全文   事物(这是复制序列的pythonic方式,如字符串或   列表)

出于好奇,你为什么不只使用=运算符?

s = 'hello';
bar = s[:] 
foo = s 

据我所知,barfoo具有相同的值。

4 个答案:

答案 0 :(得分:41)

=使用[:]创建副本进行参考。对于不可变的字符串,这并不重要,但对于列表等,这是至关重要的。

>>> s = 'hello'
>>> t1 = s
>>> t2 = s[:]
>>> print s, t1, t2
hello hello hello
>>> s = 'good bye'
>>> print s, t1, t2
good bye hello hello

但:

>>> li1 = [1,2]
>>> li = [1,2]
>>> li1 = li
>>> li2 = li[:]
>>> print li, li1, li2
[1, 2] [1, 2] [1, 2]
>>> li[0] = 0
>>> print li, li1, li2
[0, 2] [0, 2] [1, 2]

那么为什么在处理字符串时会使用它?内置字符串是不可变的,但每当你编写一个期望字符串的库函数时,用户可能会给你一些“看起来像字符串的东西” “和”的行为类似于字符串“,但它是一种自定义类型。这种类型可能是可变的,因此最好照顾它。

这种类型可能如下:

class MutableString(object):
    def __init__(self, s):
        self._characters = [c for c in s]

    def __str__(self):
        return "".join(self._characters)

    def __repr__(self):
        return "MutableString(\"%s\")" % str(self)

    def __getattr__(self, name):
        return str(self).__getattribute__(name)

    def __len__(self):
        return len(self._characters)

    def __getitem__(self, index):
        return self._characters[index]

    def __setitem__(self, index, value):
        self._characters[index] = value

    def __getslice__(self, start, end=-1, stride=1):
        return str(self)[start:end:stride]


if __name__ == "__main__":
    m = MutableString("Hello")
    print m
    print len(m)
    print m.find("o")
    print m.find("x")
    print m.replace("e", "a") #translate to german ;-)
    print m
    print m[3]
    m[1] = "a"
    print m
    print m[:]

    copy1 = m
    copy2 = m[:]
    print m, copy1, copy2
    m[1] = "X"
    print m, copy1, copy2

免责声明:这只是一个示例,展示它如何运作并激励[:]的使用。它未经测试,不完整且可能性能非常高

答案 1 :(得分:1)

它们具有相同的值,但在处理可变对象时存在根本区别。

foo = [1, 2, 3]。您指定了bar = foobaz = foo[:]。现在让我们假设您要更改bar - bar.append(4)。您检查foo和...

的值
print foo
# [1, 2, 3, 4]

现在,额外的4来自哪里?这是因为您已将bar分配给foo身份,因此当您更改其中一个时,您会更改另一个。您更改了baz - baz.append(5),但其他两个都没有发生 - 这是因为您已将{{1>}的副本分配给{{1} }}

但请注意,因为字符串是不可变的,所以并不重要。

答案 2 :(得分:0)

如果您有一个列表,结果会有所不同:

l = [1,2,3]
l1 = l
l2 = l[:]

l2是l(不同对象)的副本,而l1是l的别名,这意味着l1 [0] = 7也将修改l,而l2 [1] = 7将不会修改l。

答案 3 :(得分:0)

虽然引用一个对象并引用该对象的副本对于像string这样的不可变对象没有区别,但它们对于可变对象(和可变方法),例如list。

可变对象上的相同内容:

a = [1,2,3,4]
b = a
c = a[:]
a[0] = -1
print a    # will print [1,2,3,4]
print b    # will print [-1,2,3,4]
print c    # will print [1,2,3,4]

以上示例的pythontutor上的可视化 - http://goo.gl/Aswnl