2

If I write this:

c = []

def cf(n):
    c = range (5)
    print c
    if any((i>3) for i in c) is True:
        print 'hello'

cf(1)

print c

Then I get:

[1, 2, 3, 4]
hello
[]

I'm really new to programming, so please explain it really simply, but how do I stop Python from forgetting what c is after the function has ended? I thought I could fix it by defining c before the function, but obviously that c is different to the one created just for the function loop.

In my example, I could obviously just write:

c = range (5)
def cf(n)

But the program I'm trying to write is more like this:

b = [blah]
c = []
def cf(n):
    c = [transformation of b]
    if (blah) is True:
       'loop' cf
    else:
cf(1)
g = [transformation of c that produces errors if c is empty or if c = b]

So I can't define c outside the function.

Pokechu22
  • 4,984
  • 9
  • 37
  • 62
Patrik333
  • 53
  • 5
  • 1
    put `global c` at the top of your function, and it will use the version defined at the top-level of your file, instead of creating a new variable inside the function. – Jeremy Dec 04 '14 at 23:36
  • 1
    `global c` use this in the `cf` – Marcin Dec 04 '14 at 23:37
  • 3
    I will add the obligatory don't use global, there are almost always a better way to go. – Padraic Cunningham Dec 04 '14 at 23:50
  • @Patrik333 Note that although `global c` is a *valid* solution, it's a pretty poor one. Use `return`. – Veedrac Dec 04 '14 at 23:51
  • Note that you don't need the `is True` in your if statements. For tests that return a boolean anyway (like any() and all()), it is pure noise. For the cases where it does make a difference, `if blah:` is almost certainly what you mean over `if blah is True:`. – lvc Dec 05 '14 at 00:14
  • @Veedrac Why is it poor - is it less efficient? – Patrik333 Dec 05 '14 at 03:25
  • @Patrik333 http://www.reddit.com/r/learnpython/comments/2jo9ro/why_does_everyone_hate_global_variables/cldnytk (but yes, it is also slower). Tim B also gave a link in [his answer](http://stackoverflow.com/a/27306291/1763356). – Veedrac Dec 05 '14 at 12:22

5 Answers5

4

In python you can read global variables in functions, but you cant assigned to them by default. the reason is that whenever python finds c = it will create a local variable. Thus to assign to global one, you need explicitly specify that you are assigning to global variable.

So this will work, e.g.:

c = [1,2,3]

def cf(): 
    print(c) # it prints [1,2,3], it reads global c

However, this does not as you would expect:

c = [1,2,3]

def cf(): 
    c = 1 # c is local here.
    print(c) # it prints 1


cf()
print(c) # it prints [1,2,3], as its value not changed inside cf()

So to make c be same, you need:

c = [1,2,3]

def cf(): 
    global c
    c = 1  # c is global here. it overwrites [1,2,3]
    print(c) # prints 1


cf()
print(c) # prints 1. c value was changed inside cf()
Marcin
  • 215,873
  • 14
  • 235
  • 294
2

You can also pass the array c into the function after declaring it. As the array is a function argument the c passed in will be modified as long as we don't use an = statement. This can be achieved like this:

def cf(n, c):
  c.extend(range(5))
  print c
  if any((i>3) for i in c) is True:
    print 'hello'

if __name__ == '__main__':
  c = []
  cf(1, c)
  print c

For an explanation of this see this

This is preferable to introducing global variables into your code (which is generally considered bad practice). ref

Community
  • 1
  • 1
Tim B
  • 3,033
  • 1
  • 23
  • 28
2

To summarise a few of these answers, you have 3 basic options:

  1. Declare the variable as global at the top of your function
  2. Return the local instance of the variable at the end of your function
  3. Pass the variable as an argument to your function
chris
  • 4,840
  • 5
  • 35
  • 66
1

Try this

c = []

def cf(n):
  global c
  c = range (5)
  print c
  if any((i>3) for i in c) is True:
    print 'hello'

cf(1)

print c
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
1

If you want your function to modify c then make it explicit, i.e. your function should return the new value of c. This way you avoid unwanted side effects:

def cf(n, b):
    """Given b loops n times ...

    Returns
    ------
    c: The modified value
    """
    c = [transformation of b]
    ...
    return c  # <<<<------- This

c = cf(1)
elyase
  • 39,479
  • 12
  • 112
  • 119