Подтвердить что ты не робот

Python, почему вы использовали [:] over =

Я просто изучаю python, и я собираюсь, хотя учебники на https://developers.google.com/edu/python/strings

В разделе Строковые фрагменты

s [:] is "Hello" - опускание обоих всегда дает нам копию целого вещь (это питонический способ скопировать последовательность как строку или список)

Из любопытства, почему бы вам просто не использовать оператор =?

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

Насколько я могу сказать, оба bar и foo имеют одинаковое значение.

4b9b3361

Ответ 1

= делает ссылку, используя [:], вы создаете копию. Для строк, которые неизменяемы, это не имеет особого значения, но для списков и т.д. Это важно.

>>> 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

Отказ от ответственности: это всего лишь образец, показывающий, как он может работать, и мотивировать использование [:]. Он непроверен, неполный и, вероятно, ужасно результативен

Ответ 2

Они имеют одинаковое значение, но есть фундаментальное отличие при работе с изменяемыми объектами.

Скажите foo = [1, 2, 3]. Вы назначаете bar = foo и baz = foo[:]. Теперь предположим, что вы хотите изменить bar - bar.append(4). Вы проверяете значение foo и...

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

Теперь, откуда появился этот дополнительный 4? Это потому, что вы назначили bar идентификатор foo, поэтому при его изменении вы меняете другой. Вы меняете baz - baz.append(5), но ничего не случилось с двумя другими - это потому, что вы назначили копию от foo до baz.

Обратите внимание, что, поскольку строки неизменяемы, это не имеет значения.

Ответ 3

Если у вас есть список, результат отличается:

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

l2 является копией l (другого объекта), в то время как l1 является псевдонимом l, что означает, что l1 [0] = 7 также изменит l, тогда как l2 [1] = 7 не изменит l.

Ответ 4

Хотя ссылка на объект и ссылка на копию объекта не отличается для неизменяемого объекта, такого как строка, они выполняют для изменяемых объектов (и изменяемых методов), например, списка.

То же самое на изменяемых объектах:

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.