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
>Solution :
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&