I've got the following code, but unfortunately it only changes the value inside the list. Is there any way I can change the value outside the list, so it can be used later in the script?
street_number = "100 & 102"
street_name = "Fake Street"
suburb = "Faketown"
allvariables = [street_number, street_name, suburb]
ampersand = "&"
ampersand_escape = "&"
for i, item in enumerate(allvariables):
if isinstance(item, str):
if ampersand in item:
allvariables[i] = item.replace(ampersand,ampersand_escape)
print(allvariables) # -> ['100 & 102', 'Fake Street', 'Faketown']
print(street_number) # -> 100 & 102
The only alternative I can imagine is checking each variable individually, but I've got a LOT of variables that need to be checked so it would take forever:
if ampersand in street_number:
street_number.replace(ampersand,ampersand_escape)
if ampersand in street_name:
street_name.replace(ampersand,ampersand_escape)
if ampersand in suburb:
suburb.replace(ampersand,ampersand_escape)
But that seems extremely time consuming. Thank you in advance for your help!
P.S. just in case - I need to do a few more checks besides the ampersands
CodePudding user response:
Each variable in python (for instance, street_number
) is just a reference to something. In this case, street_number
is a reference to a string, namely "100 & 102".
When you write allvariables = [street_number, street_name, suburb]
, you are simply creating a list with elements that have been initialized by the variables. So in your list, position 0 contains a string which was copied from street_number
and has the same value "100 & 102", but there is no ongoing linkage to the variable street_number
.
So if you update allvariables[0]
to be '100 & 102', this will have no effect on the value referenced by the variable street_number
.
One way to get the result I think you want would be this:
street_number = "100 & 102"
street_name = "Fake Street"
suburb = "Faketown"
allvariableNames = ['street_number', 'street_name', 'suburb']
ampersand = "&"
ampersand_escape = "&"
ampIndices = [i for i, item in enumerate(allvariableNames) if isinstance(eval(item), str) and ampersand in eval(item)]
for i in ampIndices:
exec(f'{allvariableNames[i]} = {allvariableNames[i]}.replace(ampersand, ampersand_escape)')
print(', '.join(f"'{eval(item)}'" for item in allvariableNames)) # -> ['100 & 102', 'Fake Street', 'Faketown']
print(street_number)
Output:
'100 & 102', 'Fake Street', 'Faketown'
100 & 102
Explanation:
- instead of initializing a list using the variables you have in mind, initialize a list with the names of these variables as strings
- build a list of the indices into the variable name list for the value of the variable (obtained using the
eval()
function) contains the search pattern - use
exec()
to execute a python statement that uses the string name of the variable to update the variable's value by replacing the search pattern with the new string&
CodePudding user response:
It seems like all your variables are related to each other, so using a dictionary to store the variables might be a good idea. Like a list, you can look over it, but unlike a list, you can give its members names. Here's some example code:
address = {
"street_number": "100 & 102",
"street_name": "Fake Street",
"suburb": "Faketown",
}
ampersand = "&"
ampersand_escape = "&"
for (item, value) in address.items():
if isinstance(value, str):
if ampersand in value:
address[item] = value.replace(ampersand,ampersand_escape)
print(address)
CodePudding user response:
Strings in Python are immutable which means that once created they cannot be changed. Only a new string can be created. So what you want to do is to store the newly created string back in the same variable. for example
s = "hello"
s.upper() #does not change s.. only creates a new string and discards it
s = s.upper() # creates the new string but then overrides the value of s
Also, adding strings to the list means any manipulation you do won't affect the original string.