By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,548 Members | 1,550 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,548 IT Pros & Developers. It's quick & easy.

function that modifies a string

P: n/a
I want to make a function that does the following. I will call it
thefunc for short.
>>s = "Char"
thefunc(s)
s
'||Char>>'

I tried the following

def thefunc(s):
s = "||" + s + ">>"

The problem is that if I look at the string after I apply the function
to it, it is not modified. I realized that I am having issues with the
scope of the variables. The string in the function, s, is local to the
function and thus I am not changing the string that was inputed, but a
copy. I cannot seem to figure out how to get what I want done. Thank
you for your time.

Jul 10 '06 #1
Share this Question
Share on Google+
18 Replies


P: n/a
greenflame wrote:
I want to make a function that does the following. I will call it
thefunc for short.
>s = "Char"
thefunc(s)
s
'||Char>>'

I tried the following

def thefunc(s):
s = "||" + s + ">>"

The problem is that if I look at the string after I apply the function
to it, it is not modified. I realized that I am having issues with the
scope of the variables. The string in the function, s, is local to the
function and thus I am not changing the string that was inputed, but a
copy. I cannot seem to figure out how to get what I want done. Thank
you for your time.
You cannot do what you are trying to do directly. Strings are
immutable objects. Once a string is created, that string cannot be
modified. When you operate on a string, you produce a different
string. Functions which operate on a string should return their value:
>>def thefunc(s):
.... return '||' + s + '>>'
....
>>s = 'Char'
s = thefunc(s)
s
'||Char>>'

There /are/ a few hacks which will do what you want. However, if you
really need it, then you probably need to rethink your program design.
Remember, you can't change a string since a string is immutable! You
can change a variable to bind to another string. In the following
example, s gets rebound to the new string while t keeps the original
string value:
>>def changeString(varName):
.... globalDict = globals()
.... globalDict[varName] = '||' + globalDict[varName] + '>>'
.... return
....
>>s = 'Char'
t = s
changeString('s')
s
'||Char>>'
>>t
'Char'

Further note that this only affects variables in the global scope. I
hope this helps!

--Jason

Jul 10 '06 #2

P: n/a

greenflame wrote:
I want to make a function that does the following. I will call it
thefunc for short.
>s = "Char"
thefunc(s)
s
'||Char>>'

I tried the following

def thefunc(s):
s = "||" + s + ">>"

The problem is that if I look at the string after I apply the function
to it, it is not modified. I realized that I am having issues with the
scope of the variables. The string in the function, s, is local to the
function and thus I am not changing the string that was inputed, but a
copy. I cannot seem to figure out how to get what I want done. Thank
you for your time.
quick hack

def thefunc(s):
return s = "||" + s + ">>"
>>s = "hello"
s = thefunc(s)
print s
||hello>>
--Cheers

Jul 10 '06 #3

P: n/a
Jason wrote:
>
You cannot do what you are trying to do directly. Strings are
immutable objects. Once a string is created, that string cannot be
modified. When you operate on a string, you produce a different
string. Functions which operate on a string should return their value:
>def thefunc(s):
... return '||' + s + '>>'
...
>s = 'Char'
s = thefunc(s)
s
'||Char>>'

There /are/ a few hacks which will do what you want. However, if you
really need it, then you probably need to rethink your program design.
Remember, you can't change a string since a string is immutable! You
can change a variable to bind to another string. In the following
example, s gets rebound to the new string while t keeps the original
string value:
>def changeString(varName):
... globalDict = globals()
... globalDict[varName] = '||' + globalDict[varName] + '>>'
... return
...
>s = 'Char'
t = s
changeString('s')
s
'||Char>>'
>t
'Char'

Further note that this only affects variables in the global scope. I
hope this helps!

--Jason
Ok so let me see if I understand. The globalDict is just a dictionary
containing the name of the global variables as the keys and their
values as the values of the dictionary? Thus the inputed variable is
treated like a global variable?

Jul 10 '06 #4

P: n/a
placid wrote:
quick hack

def thefunc(s):
return s = "||" + s + ">>"
>>def thefunc(s):
return s = "||" + s + ">>"
SyntaxError: invalid syntax

Jul 10 '06 #5

P: n/a
greenflame wrote:
Jason wrote:

There /are/ a few hacks which will do what you want. However, if you
really need it, then you probably need to rethink your program design.
Remember, you can't change a string since a string is immutable! You
can change a variable to bind to another string. In the following
example, s gets rebound to the new string while t keeps the original
string value:
>>def changeString(varName):
... globalDict = globals()
... globalDict[varName] = '||' + globalDict[varName] + '>>'
... return
...
>>s = 'Char'
>>t = s
>>changeString('s')
>>s
'||Char>>'
>>t
'Char'

Further note that this only affects variables in the global scope. I
hope this helps!

--Jason

Ok so let me see if I understand. The globalDict is just a dictionary
containing the name of the global variables as the keys and their
values as the values of the dictionary? Thus the inputed variable is
treated like a global variable?
The answer to your first question is yup! You've got it. That's what
the globals() function returns. (There is also a function locals()
that returns a similar dict but for locals.)

The answer to your second question is no. The inputed *name* (the
changeString() function must be passed a string, not a variable) must
be the name of an object in the global scope for the function to work.

You almost certainly want to use a function like the thefunc() function
that Jason posted.

One other thing, you could define it like so:

def thefunc(s):
return '||%s>>' % s
Peace,
~Simon

Jul 10 '06 #6

P: n/a
On Sun, 09 Jul 2006 21:31:00 -0700, placid wrote:
>
greenflame wrote:
>I want to make a function that does the following. I will call it
thefunc for short.
>>s = "Char"
thefunc(s)
s
'||Char>>'

I tried the following

def thefunc(s):
s = "||" + s + ">>"

The problem is that if I look at the string after I apply the function
to it, it is not modified. I realized that I am having issues with the
scope of the variables. The string in the function, s, is local to the
function and thus I am not changing the string that was inputed, but a
copy. I cannot seem to figure out how to get what I want done. Thank
you for your time.

quick hack

def thefunc(s):
return s = "||" + s + ">>"
>>>s = "hello"
s = thefunc(s)
print s
||hello>>
That's not a quick hack. That's the right way to solve the problem.

Of course, another right way would be to have mutable strings in Python.
I understand why strings need to be immutable in order to work with dicts,
but is there any reason why (hypothetical) mutable strings should be
avoided in situations where they aren't needed as dictionary keys? Python
has mutable lists and immutable tuples, mutable sets and immutable frozen
sets, but no mutable string type.
--
Steven.

Jul 10 '06 #7

P: n/a
Steven D'Aprano <st***@REMOVETHIScyber.com.auwrote:
>Of course, another right way would be to have mutable strings in Python.
What significant advantage would mutable strings have over StringIO
and wrapping list manipulation in list(s) and ''.join(l). Other than
that pleasing symmetry with sets/frozensets etc.

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump
Jul 10 '06 #8

P: n/a
Of course, another right way would be to have mutable strings in Python.
I understand why strings need to be immutable in order to work with dicts,
but is there any reason why (hypothetical) mutable strings should be
avoided in situations where they aren't needed as dictionary keys? Python
has mutable lists and immutable tuples, mutable sets and immutable frozen
sets, but no mutable string type.
What's wrong about arrays of chars?

Diez
Jul 10 '06 #9

P: n/a

Diez B. Roggisch wrote:
Of course, another right way would be to have mutable strings in Python.
I understand why strings need to be immutable in order to work with dicts,
but is there any reason why (hypothetical) mutable strings should be
avoided in situations where they aren't needed as dictionary keys? Python
has mutable lists and immutable tuples, mutable sets and immutable frozen
sets, but no mutable string type.

What's wrong about arrays of chars?
Arrays of chars are dangerous. If you insist, use Python lists of
Python "chars" (strings of length 1).

If you really want a mutable string type, there's nothing in python
that keeps you from writting one yourself. You just have to be more
careful than you would be in C++, because your MutableString type would
always be passed by reference to functions, and so you'd have to be
very careful to copy it unless you want weird, unfindable bugs to crop
up in your program.

Jul 10 '06 #10

P: n/a
tac-tics wrote:
>
Diez B. Roggisch wrote:
Of course, another right way would be to have mutable strings in
Python. I understand why strings need to be immutable in order to work
with dicts, but is there any reason why (hypothetical) mutable strings
should be avoided in situations where they aren't needed as dictionary
keys? Python has mutable lists and immutable tuples, mutable sets and
immutable frozen sets, but no mutable string type.

What's wrong about arrays of chars?

Arrays of chars are dangerous. If you insist, use Python lists of
Python "chars" (strings of length 1).
Why are they more dangerous than a self-written mutable string?
If you really want a mutable string type, there's nothing in python
that keeps you from writting one yourself. You just have to be more
careful than you would be in C++, because your MutableString type would
always be passed by reference to functions, and so you'd have to be
very careful to copy it unless you want weird, unfindable bugs to crop
up in your program.
I don't buy that. You are right about the dangers - but I fail to see where
C++ gives you any protection from these pitfalls. And what disqualifies an
array of characters in python that exists and has all the methods I can
think of for a mutable string.

Regards,

Diez
Jul 10 '06 #11

P: n/a
On Mon, 10 Jul 2006 15:23:36 +0100, Sion Arrowsmith wrote:
Steven D'Aprano <st***@REMOVETHIScyber.com.auwrote:
>>Of course, another right way would be to have mutable strings in Python.

What significant advantage would mutable strings have over StringIO
and wrapping list manipulation in list(s) and ''.join(l). Other than
that pleasing symmetry with sets/frozensets etc.
Some algorithms (e.g. genetic algorithms) have natural implementations
in terms of mutable strings.

StringIO is more like a kind of file than a kind of string. It has no
methods for upper/lowercase, searching, etc. While files do have random
access, they don't have random access insertion and deletion like lists or
hypothetical mutable strings, so StringIO is no replacement at all.
--
Steven.

Jul 10 '06 #12

P: n/a
On Mon, 10 Jul 2006 16:27:03 +0200, Diez B. Roggisch wrote:
>Of course, another right way would be to have mutable strings in Python.
I understand why strings need to be immutable in order to work with dicts,
but is there any reason why (hypothetical) mutable strings should be
avoided in situations where they aren't needed as dictionary keys? Python
has mutable lists and immutable tuples, mutable sets and immutable frozen
sets, but no mutable string type.

What's wrong about arrays of chars?
Nice suggestion. However, I should point out that the methods available to
array.array('c') are quite limited compared to the methods available to
strings. Still, it would make a good basis to start with, and far better
than my initial thought of a list of chars.
--
Steven.

Jul 10 '06 #13

P: n/a
Simon Forman wrote:
greenflame wrote:
Jason wrote:
>
There /are/ a few hacks which will do what you want. However, if you
really need it, then you probably need to rethink your program design.
Remember, you can't change a string since a string is immutable! You
can change a variable to bind to another string. In the following
example, s gets rebound to the new string while t keeps the original
string value:
>
>def changeString(varName):
... globalDict = globals()
... globalDict[varName] = '||' + globalDict[varName] + '>>'
... return
...
>s = 'Char'
>t = s
>changeString('s')
>s
'||Char>>'
>t
'Char'
>
Further note that this only affects variables in the global scope. I
hope this helps!
>
--Jason
Ok so let me see if I understand. The globalDict is just a dictionary
containing the name of the global variables as the keys and their
values as the values of the dictionary? Thus the inputed variable is
treated like a global variable?

The answer to your first question is yup! You've got it. That's what
the globals() function returns. (There is also a function locals()
that returns a similar dict but for locals.)

The answer to your second question is no. The inputed *name* (the
changeString() function must be passed a string, not a variable) must
be the name of an object in the global scope for the function to work.

You almost certainly want to use a function like the thefunc() function
that Jason posted.

One other thing, you could define it like so:

def thefunc(s):
return '||%s>>' % s
Peace,
~Simon
Certainly. I do want to add a warning: do not modify the dictionary
returned from locals(). Please note the warning given at
"http://docs.python.org/lib/built-in-funcs.html#l2h-45".

--Jason

Jul 10 '06 #14

P: n/a
What's wrong about arrays of chars?

Arrays of chars are dangerous. If you insist, use Python lists of
Python "chars" (strings of length 1).

Why are they more dangerous than a self-written mutable string?
I didn't say that. I meant that arrays in the C++ sense are dangerous.

If you really want a mutable string type, there's nothing in python
that keeps you from writting one yourself. You just have to be more
careful than you would be in C++, because your MutableString type would
always be passed by reference to functions, and so you'd have to be
very careful to copy it unless you want weird, unfindable bugs to crop
up in your program.

I don't buy that. You are right about the dangers - but I fail to see where
C++ gives you any protection from these pitfalls. And what disqualifies an
array of characters in python that exists and has all the methods I can
think of for a mutable string.
C++ offers pass by value options. That makes it so you never need to
worry about messing up data that doesn't belong to you unless you
explicitly pass by reference. Python doesn't do this for you. Thus, a
mutable string class in Python requires a great deal more care since
you need to make copies of every string in every function in order to
prevent changes in one object's string from affecting another.

Jul 10 '06 #15

P: n/a
tac-tics wrote:
I didn't say that. I meant that arrays in the C++ sense are dangerous.
so what do you think Python's string type uses on the inside ?
C++ offers pass by value options. That makes it so you never need to
worry about messing up data that doesn't belong to you unless you
explicitly pass by reference. Python doesn't do this for you. Thus, a
mutable string class in Python requires a great deal more care since
you need to make copies of every string in every function in order to
prevent changes in one object's string from affecting another.
and that would be different from any other mutable Python type in
exactly what way ?

</F>

Jul 10 '06 #16

P: n/a
>>Arrays of chars are dangerous. If you insist, use Python lists of
>>Python "chars" (strings of length 1).
Why are they more dangerous than a self-written mutable string?

I didn't say that. I meant that arrays in the C++ sense are dangerous.
So what? Python's arrays are backed by arrays of the type they have,
whereas lists are represented by arrays of python objects. Both arrays
of some kind. Both hide this behind a convenient API whcih don't put any
responsibility on the programmer's shoulder. Now I ask again: where is
that dangerous, or more dangerous than writing your own mutable string?
C++ offers pass by value options. That makes it so you never need to
worry about messing up data that doesn't belong to you unless you
explicitly pass by reference. Python doesn't do this for you. Thus, a
mutable string class in Python requires a great deal more care since
you need to make copies of every string in every function in order to
prevent changes in one object's string from affecting another.
While you are technically correct, it strikes me odd that someone uses
mutable strings in a scenario where he also wants copy-semantics for
pass-by-value. That is plain stupid: create O(n) complexity to achieve
what immutable strings buy you for O(1).

So: Yes, mutable strings are dangerous. Use them only when their
benefits outweigh their risks. But you argumentation regarding C++ is
odd to say the least. Especially since the cited call-by-value semantics
doesn't come for free - designing and implementing assignment operators
and copy-constructors is a daunting task in itself.

And if you WANT to use mutable strings with a call-by-value semantic in
python, a simple decorator that scans arguments for mutable strings
could help you there.

Diez
Jul 10 '06 #17

P: n/a
On Mon, 10 Jul 2006 19:30:09 +0200, Diez B. Roggisch wrote:

[snip]
So: Yes, mutable strings are dangerous.
I'm sorry, perhaps I'm being slow today, but just why are they dangerous?
More dangerous than, say, mutable lists and mutable dicts? Unless I'm
missing something, the worst that can happen is that people will write
inefficient code, and they'll be caught out by the same sort of things
that surprise newbies about lists. E.g. using a list as a default value
in function definitions.

Use them only when their benefits outweigh their risks.
That goes without saying :)
--
Steven.

Jul 10 '06 #18

P: n/a
I'm sorry, perhaps I'm being slow today, but just why are they dangerous?
More dangerous than, say, mutable lists and mutable dicts? Unless I'm
missing something, the worst that can happen is that people will write
inefficient code, and they'll be caught out by the same sort of things
that surprise newbies about lists. E.g. using a list as a default value
in function definitions.
Well, they certainly aren't more dangerous than other mutable objects in
python. But in comparison to only dealing with immutable collections, using
immutable strings never made something impossible or even hard to do - at
least for me. Sometimes a bit harder to do efficiently.

So - the overall danger of mutability can be avoided with immutable strings
pretty neat, and thus one should (or could) go without them.

Regards,

Diez
Jul 11 '06 #19

This discussion thread is closed

Replies have been disabled for this discussion.