0

From an S.O answer:

"Don't modify strings.

Work with them as lists; turn them into strings only when needed.

... code sample ...

Python strings are immutable (i.e. they can't be modified). There are a lot of reasons for this. Use lists until you have no choice, only then turn them into strings."

Is this considered best practice?

I find it a bit odd that Python has methods that return new modified strings (such as upper(), title(), replace() etc.) but doesn't have an insert method that returns a new string. Have I missed such a method?

Edit: I'm trying to rename files by inserting a character:

import os
for i in os.listdir('.'):
    i.insert(3, '_')

Which doesn't work due to immutability. Adding to the beginning of a string works fine though:

for i in os.listdir('.'):
    os.rename(i, 'some_random_string' + i)

Edit2: the solution:

>>> for i in os.listdir('.'):                                                │··
...  os.rename(i, i[:4] + '_' + i[4:])

Slicing certainly is nice and solves my problem, but is there a logical explanation why there is no insert() method that returns a new string?

Thanks for the help.

Community
  • 1
  • 1
S1M0N_H
  • 109
  • 3
  • 9
  • No, there is no `insert` method, but you can easily do that and more than that with available methods. Is your question about insertion or about best practices? It doesn't feel specific enough. If you have a specific problem (and maybe a solution you are not sure about), why not post it here? – Lev Levitsky Jan 26 '13 at 21:30
  • Hi. I'm attempting to learn Python (again). I'm setting silly challenges for myself. This one is to rename FILE1 FILE2 FILE3 to FILE_1 FILE_2 FILE_3. Thanks. – S1M0N_H Jan 26 '13 at 21:41
  • 1
    If you know both formats in advance, you don't need to convert one to the other at all: `for i in range(1, 4): os.rename('FILE' + str(i), 'FILE_' + str(i))`. – Lev Levitsky Jan 26 '13 at 21:44
  • Thanks Lev. What if you just wanted to insert an underscore (or other character) at a particular position for every item in your loop? – S1M0N_H Jan 26 '13 at 21:54
  • `data[:4] + '_' + data[4:]` – Matthias Jan 26 '13 at 21:59
  • Yep, just use slices. And in more complex cases, `str.replace`, `str.format` or `re.sub`. – Lev Levitsky Jan 26 '13 at 22:02
  • Thanks very much! Never occurred to me. I still think insert() would be easier though... – S1M0N_H Jan 26 '13 at 22:10
  • If you REALLY want to use a function, you can create your own function to do so... It's going to use slices as well, though: http://ideone.com/P6WZLo – Rushy Panchal Jan 26 '13 at 23:23
  • `import this` : "There should be one-- and preferably only one --obvious way to do it.", "Although that way may not be obvious at first unless you're Dutch." – Derek Litz Jan 26 '13 at 23:37

3 Answers3

2

If you want to insert at a particular spot, you can use slices and +. For example:

a = "hello"
b = a[:2] + '_S1M0N_' + a[2:]

then b will be equal to he_S1M0N_llo.

Max Shron
  • 946
  • 7
  • 6
2

It's at least arguably a best practice if you are doing a very large number of modifications to a string. It is not a general purpose best practice. It's simply a useful technique for solving performance problems when doing heavy string manipulation.

My advice is, don't do it until performance becomes an issue.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

You can define a generic function that works on any sequence (strings, lists, tuples, etc.) using the slice syntax:

def insert(s, c, p):
    return s[:p] + c + s[p:]

insert('FILE1', '_', 4)
> 'FILE_1'
pyrrrat
  • 359
  • 1
  • 4