2

What I was trying to do (C code):

int a = 2, b = 3, c = 4;

int* arr[3] = {&a, &b, &c};

for (int i = 0; i < 3; ++i) {
    if (*(arr[i]) > 1) {
        *(arr[i]) = 1
    }
}

I was expecting Python to do similar pointer like behavior with this piece of code.

>>> a = 2
>>> b = 3
>>> c = 4
>>> for x in [a, b, c]:
...     if x > 1:
...             x = 1
... 
>>> a,b,c
(2, 3, 4)

How can the C code like behavior be achieved in Python?

1
  • It doesn't. The "error" happens in the loop. If you check whethe x is a (etc. for b, c), you'll see it's the same object. Commented Jan 5, 2012 at 13:25

6 Answers 6

6

Python doesn't have pointers in that sense.

Python variables are names bound to a value not a location in memory, so changing the value for one variable does not change the value for another variable with the same value.

You can achieve something a bit like you want using locals:

>>> a = 2
>>> b = 3
>>> c = 4
>>> for x in 'a','b','c':
...    if locals()[x] > 1:
...       locals()[x] = 1
... 
>>> a
1

However, I'd strongly recommend against doing this. If you post another question explaining the problem you're try to solve you'll get a more "Pythonic" way of doing it.

It may just be a case of storing your values in a dict:

>>> vals = { 'a' : 2, 'b' : '3', 'c' : 4 }
>>> for key,value in vals.items():
...     if value > 1:
...        vals[key] = 1
... 
>>> vals
{'a': 1, 'c': 1, 'b': 1}
Sign up to request clarification or add additional context in comments.

1 Comment

+10 if I could. Thank you for getting Python's semantics right. I've seen so much confusing about this topic... Identifying the main reason OP's snippet does not work as expected (by OP) and proposing a reasonable alternative didn't hurt either.
3

You should use mutable objects for that.
For example:

a = 2
b = 3
c = 4

ls = [a, b, c]

for i, val in enumerate(ls):
     if val > 1:
        ls[i] = 1

print ls

gives you:

[1, 1, 1]

if you need a, b, c:

>>> [a, b, c] = ls
>>> a
1

2 Comments

Use list comprehensions rather than explicit loops when possible.
That is right. But in this case my objective was to mimick as close as posible the OP C and python code structure.
2

Maybe this be helpfull

a,b,c  =  [ 1 if i>1 else i for i in [ a, b, c ] ]
a,b,c = map( lambda x: 1 if x>1 else x, [a,b,c] ) #lambda or name of some function

3 Comments

Note that this code is both inefficent (complexity of O(n^2) because index searches the list sequentially) and has different semantics (index returns the first index at which an object of equal value is).
Ok, I found another solution :)
This is exactly what I was trying to achieve. Thank you for this solution!
1

When you do x = 5 you change the reference, not the underlying value. Now x reference is pointing to value 5 (which is usually only single object in interpreter).

In python you code differently. What you are trying to achieve is done with a following way:

arr = [2, 3 , 4]
def foo(x):
   return x if x > 1 else x
arr = [foo(a) for a in arr]

Or can be even done in a one liner:

>>> [1 if a > 1 else a for a in arr]
[1, 1, 1]

Comments

1

I assume that what you're actually trying to do is inspect and modify some set of variables, rather than some list of values. If not, you probably want to do one of the other things listed here, namely using an actual list instead of the individual variables. I would strongly not recommend this sort of technique for most code, but it can be useful for certain metaprogramming problems.

So, with that out of the way, you can throw caution to the wind and manipulate the variables by name:

a, b, c = 2, 3, 4

for name in ['a','b','c']:
    if locals()[name] > 1:
        locals()[name] = 1

print a, b, c

Comments

0

As other answers has quite explained as why your expectations cannot be done

Here is one solution that might add to the bouquet

a,b,c = [1 if i > 1 else i for i in [a,b,c]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.