0

I have a problem that seems like it should be so simple but I can't work it out. I have this section of code:

Avalue = '2:7'
Bvalue = '4?3'
Cvalue = '5\t8'
    for x in [Avalue,Bvalue,Cvalue]:
        for illChar in ['?','/','|','*','<','>',':','\n','\t','"']:
            if illChar in x:
               x = x.replace(illChar, "")
        int(x)
        print type(x)

    print type(Avalue)

OUTPUT:

 <type 'int'>
 <type 'int'>
 <type 'int'>
 <type 'unicode'>

What I want to do is to strip out any of the illegal characters, and then change Avalue,Bvalue,Cvalue to integers rather than strings, so that Avalue becomes 27 for example.

But the above code doesn't actually change the original variable, it just changes the value of the variable x within that list which takes it's value from the original value of Avalue (or Bvalue or Cvalue etc). Now, I know I could just change each original variable individually, i.e. Avalue = int(Avalue), but if I end up having a whole load of variables to change it would seem more elegant to use a loop.

So, is there a way to alter variables by using a for loop like this?

edit: ok sorry I may have caused confusion with the example above, perhaps this might make more sense. Suppose I have the following:

Avalue = 'hello'
Bvalue = 'my name'
Cvalue = 'is'
    for x in [Avalue,Bvalue,Cvalue]:
          x = 'slimshady'
print Avalue

The above doesn't work, Avalue remains as 'hello'. Suppose I wanted Avalue Bvalue Cvalue all to be permanently changed to 'slimshady' can I do that using a loop?

psychojim
  • 59
  • 1
  • 1
  • 4
  • consider using a [regex replace (`re.sub`)](https://docs.python.org/2/library/re.html#re.sub) and a character class .. and *use* the results of side-effect-free expressions, like `int(x)` – user2864740 Sep 15 '14 at 00:16
  • how can you make a string an integer? Are you trying to just leave a numeric string by removing non digits? – Padraic Cunningham Sep 15 '14 at 00:51

3 Answers3

0

You are changing the value of the variable x. What you should do is changing directly the value in the variables Avalue, Bvalue and Cvalue. Put everything in a list and use it.

list = [Avalue,Bvalue,Cvalue]
for i in range(len(list)):
    for illChar in ['?','/','|','*','<','>',':','\n','\t','"']:
        if illChar in list[i]:
           list[i] = list[i].replace(illChar, "")
    int(list[i])
    print type(list[i])

print type(list[0])
0

To do what you asked str.translate is your best bet to remove the bad chars. You can enumerate to track the index of the list so you can reassign the value after its been cleaned and cast to an int.

inputs = [Avalue, Bvalue, Cvalue]
#convert the list of illegal chars to a string
bad_chars = "".join(['?','/','|','*','<','>',':','\n','\t','"'])
for i, item in enumerate(inputs):
    #passing None as the first arg to translate deletes all the chars referenced
    item = item.translate(None, bad_chars)
    item = int(item)
    inputs[i] = item

The use of Avalue, Bvalue variable names is redundant though in my opinion. Just read all your input into a list and access with indices.

b10n
  • 1,166
  • 9
  • 8
0

Variables in Python work a bit differently to other languages. SO user Ned Batchelder has a helpful tutorial with cute diagrams: Facts and Myths about Names and Values in Python.

You can kind of do what you're trying in the OP, but it's not a good way to do this sort of thing.

#Fun with mutability...

Avalue = ['2:7']
Bvalue = ['4?3']
Cvalue = ['5\t8']

bad_chars = '?/|*<>:\n\t"'

all_values = (Avalue, Bvalue, Cvalue)
print 'Before:', all_values

for x in all_values:
    x[0] = int(x[0].translate(None, bad_chars))

print 'After: ', all_values
print Avalue, Bvalue, Cvalue

Output:

Before: (['2:7'], ['4?3'], ['5\t8'])
After:  ([27], [43], [58])
[27] [43] [58]

A slightly better approach is to do this:

bad_chars = '?/|*<>:\n\t"'

#Remove bad_chars from string s and convert to int
def convert(s):
    return int(s.translate(None, bad_chars))

Avalue = '2:7'
Bvalue = '4?3'
Cvalue = '5\t8'

Avalue, Bvalue, Cvalue = [convert(s) for s in (Avalue, Bvalue, Cvalue)]

print Avalue, Bvalue, Cvalue

But as Michelly Menezes and b10n said, it's better to not have separate names for Avalue, Bvalue, Cvalue. Just put them all into some kind of container, eg a tuple, list or dict.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182