Home > Enterprise >  Need to check all my variables for an ampersand, I put variables in a list and check using a for loo
Need to check all my variables for an ampersand, I put variables in a list and check using a for loo

Time:05-26

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 &amp

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.

  • Related