2

Before you say to use a dictionary, I want to change the value of the actual variable.

This is what happens with the standard dict strategy: (Note that I'm not necessarily using a list, the value could be a complex class type or just a regular int)

>>> dict = {}
>>> x = [1,2,3]
>>> dict["x"] = x
>>> x
[1, 2, 3]
>>> dict["x"]
[1, 2, 3]
>>> dict["x"] = [4,5,6]
>>> dict["x"]
[4, 5, 6]
>>> x
[1, 2, 3]
>>>

Anyone know a way to do this so that the actual contents of x are changed as well? copy.deepcopy doesn't do the trick either. (as in 'dict["x"] = copy.deepcopy(x)')

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
Inbl
  • 630
  • 2
  • 5
  • 18
  • 2
    You have not convinced me that you don't need a dictionary. – Lev Levitsky Mar 27 '14 at 20:20
  • Why do you want to access variables by their names? See [Keep data out of variable names](http://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html) – David Robinson Mar 27 '14 at 20:21
  • @LevLevitsky I would like x to contain [4,5,6] after my assignment. – Inbl Mar 27 '14 at 20:21
  • But why do you want to access a variable `x` using a string? Why not just continue to access it as `dict["x"]`? – David Robinson Mar 27 '14 at 20:23
  • @DavidRobinson I happen to work with software that has a large dataset that I need to manipulate with python. I can only access them by their names. Can't provide any more details I'm afraid. To answer your second question, the variable x has been initialized previously and there are dependencies in other parts of the system that require x to reflect the changes. – Inbl Mar 27 '14 at 20:23
  • Keeping a large dataset as Python variables, where you access them by their Python names, isn't a good strategy. It would be much better to keep them within a dictionary or other structure. – David Robinson Mar 27 '14 at 20:24
  • They're stored in some class hierarchy that I have no influence over. – Inbl Mar 27 '14 at 20:26
  • 1
    I don't own the code, can't refactor it. – Inbl Mar 27 '14 at 20:27
  • You say that there are dependencies in other parts of the system that have already initialized `x`, but also that `x` can be an int. This is dangerous: anywhere x has already been used you can't change it in this way. You could give the global `x` a new value, but that gets you into more trouble. – David Robinson Mar 27 '14 at 20:28
  • Yeah, I wish it was set up in a different way. – Inbl Mar 27 '14 at 20:32

2 Answers2

4

Use slice assignment:

>>> d = {}
>>> x = [1, 2, 3]
>>> d['x'] = x
>>> d['x'][:] = [4, 5, 6]
>>> x
[4, 5, 6]
>>> d['x']
[4, 5, 6]

For other data types make sure you modify them in-place instead of assigning them to new variables. Note that for immutable data types like int, strings etc there are no in-place operations available.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • This won't work for the OP: `(Note that I'm not necessarily using a list, the value could be a complex class type or just a regular int)`. – David Robinson Mar 27 '14 at 20:23
  • Sure, but the *principle* is the same -- modify the data in-place, don't overwrite it. – Thane Brimhall Mar 27 '14 at 20:24
  • 2
    @ThaneBrimhall: there's no way to modify an int in place. – David Robinson Mar 27 '14 at 20:25
  • Actually, it complains if I'm using longs, for example. (" 'long' object does not support item assignment") – Inbl Mar 27 '14 at 20:25
  • There's no way to reference the same `int` in multiple places either. – Thane Brimhall Mar 27 '14 at 20:25
  • 1
    @ThaneBrimhall: But the value of an `int` can be changed, (`x = 1`, or `exec("%s = 1" % varname)` I suppose) which is presumably what the OP wants (even though it's a bad idea). – David Robinson Mar 27 '14 at 20:31
  • @Inbl It is impossible to update all the references of a long/int by just by updating any one of the references, all operations on them return a new object. About the error: slice assignment is a list specific operation, so it won't work with longs. – Ashwini Chaudhary Mar 27 '14 at 20:32
  • @DavidRobinson Yes, I know. I just keep hoping the OP is mistaken about what he/she wants and it's only an issue for mutable types. ;) – Thane Brimhall Mar 27 '14 at 20:34
  • Why is exec a bad idea? (Just curious) – Inbl Mar 27 '14 at 21:15
2

this is a horrible idea and stinks of horrible code smell ... dont do this you need to refactor the code to be sensible .... this is a terrible idea but if you want

mutables = {
"x":x,"y":y,"Z":Z #make sure the dict key is exactly the same as var name
}

mutables['x'] = [5,6,7]
for k,v in mutables.items():
    globals()[k] = v

note that you will need to be in the same global scope as the original variables

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Yeah I know it's a bad situation, I wish the owners of the code would refactor it because I don't have permission to change it. – Inbl Mar 27 '14 at 21:16