-6

NOTE - This is NOT the same as all the other questions/answers about this - Read carefully [and remember to test before you reply if you're not 100% certain it works]:-

I do NOT want to create a new reference to an object that is a copy of my original one, minus the last character, I want to actually remove the last character. See this example:-

def remo(dat):
    for line in dat:
        line=line[:-1] # THIS LINE IS WRONG.  What do I put here?
        print("new line is:"+line)
    return dat

s=['fred','wilma']

n=remo(s);

print(s)
print(n)

Running the above, as you can see, returns the wrong answers:-

python  demo.py
new line is:fre
new line is:wilm
['fred', 'wilma']
['fred', 'wilma']

What is the real way to actually remove the last character?

  • 5
    Python strings are immutable. – jasonharper Sep 27 '20 at 03:11
  • Does this answer your question? [Aren't Python strings immutable? Then why does a + " " + b work?](https://stackoverflow.com/questions/9097994/arent-python-strings-immutable-then-why-does-a-b-work) – RichieV Sep 27 '20 at 03:14
  • 2
    Also, it is good to explain a little more context about the reasons behind a request, that way you can get better answers than just *it is not possible*... – RichieV Sep 27 '20 at 03:17

3 Answers3

3

You can't do this. Python's str is immutable by intent and design. There are very limited exceptions to this that constitute implementation details (In CPython, mystr += 'abc' mutates in place if and only if the string bound to mystr has no other references to it), but there is no means of making this work for other arbitrary mutations, nor make it work portably in all Python interpreters. If your design requires mutable str, your design does not work in Python; the best you could do is write a str-like class that implements your chosen behaviors, or settle for using a list of length 1 strs, mutating the list as needed (and eventually ''.joining it back to a str when you need a real str).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • 1
    Note: As always, you *could* bypass these restrictions by writing your own Python C extension that violated all the rules. You would be a fool to do so, and would likely crash the interpreter or create massive inconsistencies by the necessary `realloc`s to make the `str` do what you want. It's not part of the answer because it's neither practical, nor possible to do portably in pure Python. – ShadowRanger Sep 27 '20 at 03:20
0

when you use the for loop, line is a local variable of the value not the reference, you must use indices to access the original reference and modify it. If you want the original list to be unmodified, then you can pass a copy of the list to remo instead.

def remo(dat):
    for i in range(len(dat)):
        dat[i] = dat[i][:-1]
        print("new line is: " + dat[i])
    return dat

s = ['fred', 'wilma']
n = remo(s)
print(s)  # ['fre', 'wilm'] since we modified original value.
print(n)  # ['fre', 'wilm']
Jack Ashton
  • 156
  • 5
0

Update: I found the answer - ALL PYTHON STRINGS ARE IMMUTABLE - you can NEVER remove the last character.

The work-around is to replace all the references with new ones, like this:-

def remo(dat):
    for i in range(0 , len(dat)):
        dat[i]=dat[i][:-1]
        print("new line is:"+dat[i])
    return dat

s=['fred','wilma']

n=remo(s)

print(s)
print(n)

Which now works (note that it modifies the original too):

$ python   demo.py   
new line is:fre
new line is:wilm
['fre', 'wilm']
['fre', 'wilm']