This page is for you if you want a clear answer to “how do I copy a string?” without wading through tricks that do not help day to day. Python’s str type is immutable, so the usual answer is a plain assignment; slicing and str() are optional and copy.copy / deepcopy are almost never worth it for strings alone.
The sections below give the short answer first, then assignment, why that is safe, slicing and str(), the copy module, how normal string methods relate to “new text,” common mistakes, a one-screen table, and a recap.
Tested on: Python 3.13.3; kernel 6.14.0-37-generic.
Can you copy a string in Python?
Yes. For most programs you “copy” a string by binding another variable to the same value (b = a) or by building a new str when you transform it (for example with string formatting or replace). You do not need exotic patterns unless you have an unusual API that cares about object identity.
Best way to copy a string in Python
Start with the form people search for: two names, one piece of text, and a print so you can run it immediately.
text = "hello"
copy_text = text
print(copy_text)When you run it, you should see hello on one line. For strings, assignment is usually enough because str is immutable: you cannot change the characters of the existing object in place, so sharing that object through two names is normally safe. If you need another variable with the same characters, copy_text = text is the idiomatic approach.
Copy string using assignment
Assignment never mutates a string; it binds the name on the left to the object on the right. After copy_text = text, both names refer to the same str instance until you rebind one of them.
text = "hello"
copy_text = text
print(text, copy_text)
print(text == copy_text)You should see hello hello and True for value equality. For everyday code, treat that as your “copy.” For contrast with containers, see copy a list (shallow vs deep), where sharing references matters much more.
Why assignment is safe for strings
Immutability means no method and no statement can alter the characters of an existing str in memory; operations that look like edits return a new str (or another type) and leave the old value unchanged. That is why two variables pointing at the same string do not step on each other the way two variables can share one list and see in-place append effects.
text = "hello"
copy_text = text
try:
text[0] = "H"
except TypeError as err:
print("cannot assign to str index:", err)Running this prints a TypeError message: item assignment is not allowed on str. So “copying” is really about names and values: either share the value safely or build a new string when you transform it.
Copy string using slicing
Slicing with [:] returns a string with the same sequence of characters as the original. For immutable strings you should not rely on whether CPython stores that result as a brand-new object or reuses an existing one; what matters for your program is the text, not id. See Python substring for index-based extraction beyond full-string copies.
text = "hello"
same_chars = text[:]
print(same_chars)
print(text == same_chars)You should see hello twice and True. Use slicing when you want a clear “give me the whole string again” style or when you slice a substring anyway; do not use slicing as a hack to force a distinct object—Python does not document that guarantee for arbitrary strings.
Copy string using str()
Calling str(x) always produces a str. For an argument that is already a str, you get the same characters; people sometimes use str(value) at API boundaries to normalize types (for example after reading config or numbers).
text = "hello"
normalized = str(text)
print(normalized)
print(text == normalized)You should see hello and True. Prefer plain assignment when you already know the value is a string; use str() when you want explicit conversion from another type.
copy.copy() and copy.deepcopy() with strings
The copy module is aimed at compound objects: assignment does not duplicate those objects, so shallow and deep copies exist to duplicate containers and their contents. For a bare str, the same immutability argument applies—there is nothing nested to duplicate.
import copy
text = "hello"
a = copy.copy(text)
b = copy.deepcopy(text)
print(a)
print(b)Both lines print hello. These calls work, but they are unnecessary for strings in normal application code; reach for copy.copy / deepcopy when you have mutable trees (lists, dicts, custom objects).
String methods create new strings
Methods such as replace, upper, and lower return a new str when they need different text; they are for transforming content, not for “copying” in the sense of duplicating an unchanged value. Think of them as producing a new string for the next step of your logic, or use Python concatenate strings when you are assembling text from pieces.
text = "hello"
loud = text.upper()
print(text, loud)You should see hello HELLO: text is unchanged because upper returned a new string. That behavior is the same immutability rule as before, just with a method instead of an operator.
Common mistakes when copying strings
- Treating assignment as “unsafe” for strings in the same way as shared lists: for
str, shared read-only use is the norm. - Expecting in-place mutation:
text.upper()does not changetext; it returns a new string and you must assign it if you want a new name to hold the result. - Calling
deepcopyon plain strings in production pipelines: it adds noise and cost without semantic benefit. - Using
replace,join, or* 1only to “force” a copy: readers cannot tell your intent, and the language does not promise a particular object identity from those forms. - Using
id(a) == id(b)to prove copying for strings: identity is implementation-dependent for interned literals and small strings; compare with==when you care about text. - Confusing copying with modification: changing “the string” in Python means binding a name to a new
stror using a method that returns one, not editing bytes in place.
This example shows rebinding after a method call: text moves to a new object; copy_text still refers to the original spelling.
text = "hello"
copy_text = text
text = text.upper()
print(text)
print(copy_text)You should see HELLO then hello: upper produced a new string and was assigned back to text, while copy_text still points at the old "hello" object.
Python copy string quick reference table
| Need | Use |
|---|---|
| Same text under another variable | new = old |
| Same character sequence via slicing | new = old[:] (value-focused; do not rely on id) |
Normalize to str from another type |
new = str(value) |
Shallow copy of a string with copy |
Unnecessary for typical code |
| Deep copy of a string | Unnecessary for typical code |
| Change the visible text | Build a new string (replace, format, concatenation, etc.) |
| Compare text | a == b |
| Compare object identity | a is b (rarely needed for copying decisions on str) |
Summary
For Python strings, “copying” usually means assigning another name to the same immutable value (copy_text = text) or creating a new string when you transform text. Slicing [:] and str() are fine when they express intent, but you should not build correctness on object identity for str. The copy module’s shallow and deep helpers are for compound mutable structures, not for everyday string handling. When you outgrow single values and need shared-container semantics, study shallow versus deep copies on lists and nested data.

