2

I have a short method with helps me build some url strings in Python, but I'd like to learn the Pythonic way to do it. Here is what I have:

for url in some_list:
    url = constant_prefix + url

I saw somewhere that you can use += in Python, but I imagine there must be a better way. I'd just like to be able to append to some string and store the result back into the same variable.

user3270760
  • 1,444
  • 5
  • 23
  • 45
  • Possible duplicate of [Which is the preferred way to concatenate a string in Python?](http://stackoverflow.com/questions/12169839/which-is-the-preferred-way-to-concatenate-a-string-in-python) – Eli Korvigo Jan 24 '17 at 18:55

3 Answers3

3

The only way to do it is to reassign every element in the list. Here's the simplest way for your example:

some_list = [constant_prefix + url for url in some_list]

In Python strings are immutable so there's no way to update a string in place, you must replace it with another string.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • CPython does mutate the string http://stackoverflow.com/questions/25503703/why-is-variable1-variable2-much-faster-than-variable1-variable1-variable2 – Chris_Rands Jan 24 '17 at 19:01
  • @Chris_Rands that's an optimization applied in the background by Python itself. This optimization only occurs if there are no other outstanding references to the string. From a conceptual point of view it's identical to creating a new string. – Mark Ransom Jan 24 '17 at 19:07
2

Strings are immutable. You can change a variable that references a string, so that it references a new string, but never actually modify a str object.

x = "Hello"       # x references the "Hello" string
x = x + " World!" # x references a NEW "Hello World!" string

The actual string object holding "Hello" never changes. It only gets swapped for another string object.

So, instead of modifying the strings in your list (impossible), you need to change the items in the list for new strings.

for index, url in enumerate(some_list):
    some_list[index] = constant_prefix + url

The old string objects you're no longer using are discarded, and replaced in the list by the new strings.

Your previous version only modified the url variable, with no effect outside the iteration loop.

Mark Ransom, in his answer, suggested the more pythonic way: creating a new list using a comprehension:

new_urls = [constant_prefix + url for url in original_urls]

Give him an upvote =)

salezica
  • 74,081
  • 25
  • 105
  • 166
0

I've asked myself with the same question and the best option I've found is to use str.format:

for url in some_list:
    url = "{}{}".format(constant_prefix, url)

If you want to modify urls which are in the list use loop below:

for index, url in enumerate(some_list):
    some_list[index] = "{}{}".format(constant_prefix, url)

See more about string formatting in SO Python string formatting: % vs. .format question.

Good luck!

Community
  • 1
  • 1
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82