53

I have a function that parses a file into a list. I'm trying to return that list so I can use it in other functions.

def splitNet():
    network = []
    for line in open("/home/tom/Dropbox/CN/Python/CW2/network.txt","r").readlines():
        line = line.replace("\r\n", "")
        line = string.split(line, ',')
        line = map(int, line)
        network.append(line)
    return network

When I try to print the list outside of the function (for debugging) I get this error:

NameError: name 'network' is not defined

Is there something simple I am doing wrong or is there a better way to pass variables between functions without using globals?

Thomas Mitchell
  • 1,071
  • 2
  • 16
  • 29
  • 2
    Can you add the code where you assign network back to a variable in scope and print it? – sberry Feb 16 '12 at 18:36
  • your splitNet() function looks alright. Could you post the code tht prints the netwark-list? – alex Feb 16 '12 at 18:37
  • If you want to pass variables between functions: why not using parameters? Why avoid globals? You can also put your function as methods and save the result inside the class instance no ? – tito Feb 16 '12 at 18:37
  • I'm guessing you've found the problem judging from what you said because I don't do anything like that. At the moment I am just calling the function so it runs and then calling `print network` – Thomas Mitchell Feb 16 '12 at 18:38
  • Hi, i see you reverted my edit. I would argue, you should provide code that illustrates the problem and can be reproducible. Right now it is not complete. This might help: https://stackoverflow.com/help/mcve – aaaaa says reinstate Monica Apr 09 '19 at 15:50

8 Answers8

64

Variables cannot be accessed outside the scope of a function they were defined in.

Simply do this:

network = splitNet()
print network
Alex Coplan
  • 13,211
  • 19
  • 77
  • 138
18

I assume you are not assigning the returned value to a variable in scope.

ie. you can't do

splitNet()
print network

instead you would

network = splitNet()
print network

or for that matter

my_returned_network_in_scope = splitNet()
print my_returned_network_in_scope

otherwise you could declare network outside of the splitNet function, and make it global, but that is not the recommended approach.

Alex Coplan
  • 13,211
  • 19
  • 77
  • 138
sberry
  • 128,281
  • 18
  • 138
  • 165
  • 1
    @Alex: Thanks for the edit, yes a typo. Going back and forth from Java to Python to PHP to Go to Erlang to C++... messes me up something awful. – sberry Feb 16 '12 at 19:17
  • Know what you mean... I've just started with Python and I've started dropping them in my PHP/Objective-C now! – Alex Coplan Feb 16 '12 at 20:27
8

The names of variables in a function are not visible outside, so you need to call your function like this:

networks = splitNet()
print(networks)

A couple of other notes:

  • You may want to convert your function to an iterator, using yield.
  • You don't need to call readlines; the function itself is an iterator.
  • Your function may be leaking the file handle. Use the with statement.
  • You can use str.split, which is more readable and easier to understand than string.split.
  • Your file looks to be a CSV file. Use the csv module.

In summary, this is how your code should look like:

import csv
def splitNet():
    with open("/home/tom/Dropbox/CN/Python/CW2/network.txt") as nf:
        for line in csv.reader(nf, delimiter=','):
            yield map(int, line)
network = list(splitNet())
print (network)
Community
  • 1
  • 1
phihag
  • 278,196
  • 72
  • 453
  • 469
5

Your function is returning a list so you have to assign it to a variable and than try to print it.

network = splitNet()
print network

For example

>>> def mylist():
...    myl = []
...    myl.append('1')
...    return myl
...
>>> my_list = mylist()
>>> my_list
['1']
>>>
RanRag
  • 48,359
  • 38
  • 114
  • 167
2

Have you actually called the function yet? This works fine (in the Python interpreter)

 >>> def f():
 ...   network = []
 ...   network.append(1)
 ...   network.append(2)
 ...   network.append(3)
 ...   return network
 ...
 >>> network = f()
 >>> print network
 [1, 2, 3]
Chris Taylor
  • 46,912
  • 15
  • 110
  • 154
1

You may declare the name of the variable assigned to the list as global, like this:

def get_list():
    global destination_list
    destination_list = []
    destination_list.extend(('1','2','3'))
    return destination_list

get_list()
print(destination_list)
Victor
  • 11
  • 1
  • True, but not the best way. Since the value is returned, it should be assigned rather than put in the global scope. – mbomb007 Apr 28 '16 at 19:04
1
L=[1, 2, 3]

def rl(l): 
    return l

[*ll] = rl(L) # ll is in a list

ll
# >>> [1, 2, 3]

*t, = rl(L)   # ll is in a tuple

t
# >>> [1, 2, 3]
olinox14
  • 6,177
  • 2
  • 22
  • 39
0

If you want to return an item or list from a definition, you could define it before hand and use it as a variable during the initial writing of said definition. Unless it has to be defined within the definition. In this case you won't need to write in a return command at the end.

network = []

def splitNet(network):
    for line in open("/home/tom/Dropbox/CN/Python/CW2/network.txt","r").readlines():
        line = line.replace("\r\n", "")
        line = string.split(line, ',')
        line = map(int, line)
        network.append(line)

print network # Will print the list you've appended. But it is now a usable object.