I am just learning python and I am going though the tutorials on https://developers.google.com/edu/python/strings
我正在学习python,我将通过https://developers.google.com/edu/python/strings上的教程
Under the String Slices section
在“字符串切片”部分下
s[:] is 'Hello' -- omitting both always gives us a copy of the whole thing (this is the pythonic way to copy a sequence like a string or list)
s [:]是'Hello' - 省略两者总是给我们一个整体的副本(这是复制像字符串或列表的序列的pythonic方式)
Out of curiosity why wouldn't you just use an =
operator?
出于好奇,你为什么不使用一个=运算符?
s = 'hello';
bar = s[:]
foo = s
As far as I can tell both bar
and foo
have the same value.
据我所知,bar和foo都有相同的值。
4 个解决方案
#1
40
=
makes a reference, by using [:]
you create a copy. For strings, which are immutable, this doesn't really matter, but for lists etc. it is crucial.
=通过使用[:]创建一个副本来进行引用。对于不可变的字符串,这并不重要,但对于列表等,这是至关重要的。
>>> s = 'hello'
>>> t1 = s
>>> t2 = s[:]
>>> print s, t1, t2
hello hello hello
>>> s = 'good bye'
>>> print s, t1, t2
good bye hello hello
but:
>>> 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]
So why use it when dealing with strings? The built-in strings are immutable, but whenever you write a library function expecting a string, a user might give you something that "looks like a string" and "behaves like a string", but is a custom type. This type might be mutable, so it's better to take care of that.
那么为什么在处理字符串时使用它呢?内置字符串是不可变的,但每当你编写一个期望字符串的库函数时,用户可能会给你一些“看起来像字符串”和“表现得像字符串”的东西,但它是一种自定义类型。这种类型可能是可变的,因此最好照顾它。
Such a type might look like:
这样的类型可能如下所示:
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
Disclaimer: This is just a sample to show how it could work and to motivate the use of [:]
. It is untested, incomplete and probably horribly performant
免责声明:这只是一个示例,展示它如何工作并激励[:]的使用。它是未经测试的,不完整的,可能性能非常高
#2
1
They have the same value, but there is a fundamental difference when dealing with mutable objects.
它们具有相同的值,但在处理可变对象时存在根本区别。
Say foo = [1, 2, 3]
. You assign bar = foo
, and baz = foo[:]
. Now let's say you want to change bar
- bar.append(4)
. You check the value of foo
, and...
说foo = [1,2,3]。你指定bar = foo和baz = foo [:]。现在让我们说你要改变bar - bar.append(4)。你检查foo的值,然后......
print foo
# [1, 2, 3, 4]
Now where did that extra 4
come from? It's because you assigned bar
to the identity of foo
, so when you change one you change the other. You change baz
- baz.append(5)
, but nothing has happened to the other two - that's because you assigned a copy of foo
to baz
.
现在,额外的4来自哪里?这是因为你为foo的身份分配了bar,所以当你改变一个时你改变了另一个。你改变了baz - baz.append(5),但是其他两个都没有发生 - 那是因为你给了baz一份foo的副本。
Note however that because strings are immutable, it doesn't matter.
但请注意,因为字符串是不可变的,所以无关紧要。
#3
0
If you have a list the result is different:
如果您有一个列表,结果会有所不同:
l = [1,2,3]
l1 = l
l2 = l[:]
l2 is a copy of l (different object) while l1 is an alias of l which means that l1[0]=7 will modify also l, while l2[1]=7 will not modify l.
l2是l(不同对象)的副本,而l1是l的别名,这意味着l1 [0] = 7也将修改l,而l2 [1] = 7将不修改l。
#4
0
While referencing an object and referencing the object's copy doesn't differ for an immutable object like string, they do for mutable objects (and mutable methods), for instance list.
虽然引用一个对象并引用该对象的副本对于像string这样的不可变对象没有区别,但它们对于可变对象(和可变方法),例如list。
Same thing on mutable objects:
可变对象上的相同内容:
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]
A visualization on pythontutor of the above example - http://goo.gl/Aswnl.
上面例子中pythontutor的可视化 - http://goo.gl/Aswnl。
#1
40
=
makes a reference, by using [:]
you create a copy. For strings, which are immutable, this doesn't really matter, but for lists etc. it is crucial.
=通过使用[:]创建一个副本来进行引用。对于不可变的字符串,这并不重要,但对于列表等,这是至关重要的。
>>> s = 'hello'
>>> t1 = s
>>> t2 = s[:]
>>> print s, t1, t2
hello hello hello
>>> s = 'good bye'
>>> print s, t1, t2
good bye hello hello
but:
>>> 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]
So why use it when dealing with strings? The built-in strings are immutable, but whenever you write a library function expecting a string, a user might give you something that "looks like a string" and "behaves like a string", but is a custom type. This type might be mutable, so it's better to take care of that.
那么为什么在处理字符串时使用它呢?内置字符串是不可变的,但每当你编写一个期望字符串的库函数时,用户可能会给你一些“看起来像字符串”和“表现得像字符串”的东西,但它是一种自定义类型。这种类型可能是可变的,因此最好照顾它。
Such a type might look like:
这样的类型可能如下所示:
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
Disclaimer: This is just a sample to show how it could work and to motivate the use of [:]
. It is untested, incomplete and probably horribly performant
免责声明:这只是一个示例,展示它如何工作并激励[:]的使用。它是未经测试的,不完整的,可能性能非常高
#2
1
They have the same value, but there is a fundamental difference when dealing with mutable objects.
它们具有相同的值,但在处理可变对象时存在根本区别。
Say foo = [1, 2, 3]
. You assign bar = foo
, and baz = foo[:]
. Now let's say you want to change bar
- bar.append(4)
. You check the value of foo
, and...
说foo = [1,2,3]。你指定bar = foo和baz = foo [:]。现在让我们说你要改变bar - bar.append(4)。你检查foo的值,然后......
print foo
# [1, 2, 3, 4]
Now where did that extra 4
come from? It's because you assigned bar
to the identity of foo
, so when you change one you change the other. You change baz
- baz.append(5)
, but nothing has happened to the other two - that's because you assigned a copy of foo
to baz
.
现在,额外的4来自哪里?这是因为你为foo的身份分配了bar,所以当你改变一个时你改变了另一个。你改变了baz - baz.append(5),但是其他两个都没有发生 - 那是因为你给了baz一份foo的副本。
Note however that because strings are immutable, it doesn't matter.
但请注意,因为字符串是不可变的,所以无关紧要。
#3
0
If you have a list the result is different:
如果您有一个列表,结果会有所不同:
l = [1,2,3]
l1 = l
l2 = l[:]
l2 is a copy of l (different object) while l1 is an alias of l which means that l1[0]=7 will modify also l, while l2[1]=7 will not modify l.
l2是l(不同对象)的副本,而l1是l的别名,这意味着l1 [0] = 7也将修改l,而l2 [1] = 7将不修改l。
#4
0
While referencing an object and referencing the object's copy doesn't differ for an immutable object like string, they do for mutable objects (and mutable methods), for instance list.
虽然引用一个对象并引用该对象的副本对于像string这样的不可变对象没有区别,但它们对于可变对象(和可变方法),例如list。
Same thing on mutable objects:
可变对象上的相同内容:
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]
A visualization on pythontutor of the above example - http://goo.gl/Aswnl.
上面例子中pythontutor的可视化 - http://goo.gl/Aswnl。