0

I want to make a function that does the following:

def func(*args):
    for arg in args:
        arg+=1

a = 5
b = 6
c = 7
func(a,b,c)
print("%i,%i,%i"%(a,b,c))

I want it to return:

6,7,8

How would I do this?

user3808430
  • 216
  • 1
  • 8

5 Answers5

4

You can’t! Ta-da.

Python does not support pass-by-reference in any form. Return values instead:

def func(*args):
    return [arg + 1 for arg in args]

a = 5
b = 6
c = 7
a, b, c = func(a, b, c)
print("%i,%i,%i" % (a, b, c))
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Lists are passed by reference. – cdonts Jul 12 '14 at 22:19
  • @cdonts: No, lists *are* references. – Ry- Jul 12 '14 at 22:20
  • Although it may be technically true that Python doesn't support pass by reference, I think it's misleading to say it that way, because it immediately makes people ask why it works differerently for lists (as witnessed by the numerous other questions about this on StackOverflow). It's better to just say what operations can (mutation) and cannot (name rebinding in calling scope) be done in a function. – BrenBarn Jul 12 '14 at 22:21
  • @BrenBarn: Well, people have been misled to believe that passing by reference is the same thing as passing a reference, and I’d like to correct that too. – Ry- Jul 12 '14 at 22:23
  • @false: Yes, but you don't accomplish that by just saying "Python doesn't support passing by reference" without explaining the difference (or linking to other questions that do). – BrenBarn Jul 12 '14 at 22:24
0

You can't, at least not with integer values. Integers are immutable, so you can't change their values, and a function doesn't have access to the namespace of its caller, so you can't rebind the variables (i.e., assign a new value to the variable a outside the function). See this question and various others about what you can and cannot do to affect variables in functions.

If your variables are mutable types like lists, you can achieve a similar effect by mutating the list's value:

def func(*args):
    for arg in args:
        arg[0] += 1

a = [5]
b = [6]
c = [7]
func(a,b,c)
print("%i,%i,%i"%(a,b,c))

However, you should think about why you want to do this. It may be better to simply return the values and assign them outside the function.

Community
  • 1
  • 1
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
0

You can't do this, because when you pass in a variable, it takes it in as its value, not as its variable.

Instead, return the value:

def func(*args):
    args = list(args)
    for i in range(len(args)):
        args[i]+=1
    return args

a = 5
b = 6
c = 7
a, b, c = func(a,b,c)
print("%i,%i,%i"%(a,b,c))

Which outputs:

>>> print("%i,%i,%i"%(a,b,c))
6,7,8
>>> 
ZenOfPython
  • 891
  • 6
  • 15
0

3 posts to tell "You can't" But "Impossible n'est pas français". Python is the lingua franca of programming languages. So it's possible:

#!/usr/bin/env python                                                                                                                                                              

def func(args):
    for i in range(len(args)):
        args[i] += 1

abc = [5, 6, 7]
func(abc)
print("%i,%i,%i" % tuple(abc))

actually prints

6,7,8
Julien Palard
  • 8,736
  • 2
  • 37
  • 44
  • That doesn’t do the same thing, though. You can’t pass it three different variables as `[a, b, c]`. – Ry- Jul 12 '14 at 22:31
  • Yes but the question does not mention the fact that he needs to pass three different variables, so I gave it a try ;) – Julien Palard Jul 13 '14 at 07:21
0

You can't do it easily because Python doesn't pass immutable objects such as integers by reference. However if you pass the function the names of objects in the current scope, you can achieve your goal like this:

import sys

def func(*args):
    namespace = sys._getframe(1).f_globals  # caller's globals
    for arg in args:
        namespace[arg] += 1

a = 5
b = 6
c = 7
func('a','b','c')  # note variable *names* passed to function
print("%i,%i,%i" % (a,b,c)) # -> 6,7,8
martineau
  • 119,623
  • 25
  • 170
  • 301
  • Python passes ints exactly as it passes lists: as a reference. But as you say, ints are immutable, so there's no way to modify the referenced int. – Ned Batchelder Jul 12 '14 at 22:51
  • Regardless, given a name and its namespace, it's possible to change what object the name refers to. – martineau Jul 12 '14 at 22:56