4

I have a simple function to read the csv file and extracts the first coloum from it:

import csv 

def pass_username():
    with open('test.csv', 'r') as csvfile:
        spamreader = csv.reader(csvfile, delimiter=',')
        for row in spamreader:
            return row[0]

When I call this function as:

a = pass_username()
print a 

This only prints the first element. However, when I replace return word with print as print row[0] and call the function as pass_username() it prints all the elements. I want to assign that function to a variable thus I want to use return. How to fix it?

Content of test.csv:

"test@gmail.com","rockon"
"hello@gmail.com","hey"
"hithere@gmail.com","ok"
"hellosir@gmail.com","password"
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
user1881957
  • 3,258
  • 6
  • 34
  • 42

3 Answers3

5

As the other people who answered said, you can accumulate the results into a list and return that. Another way though, would be to replace return with yield which causes your function to return an iterable type object that produces the items you yield when you decide to iterate over it later (possibly with a for loop).

See: What does the "yield" keyword do in Python?

Here is how you would use it with your code:

import csv 

def pass_username():
    with open('test.csv', 'r') as csvfile:
        spamreader = csv.reader(csvfile, delimiter=',')
        for row in spamreader:
            yield row[0]

username_generator = pass_username()

# iterate through the usernames with a for loop
for name in username_generator:
    print name
# call the list constructor which causes it to produce all of the names
print list(pass_username())

Keep in mind that the usernames are produced as they are needed, so you can, for example, do username_generator.next() which will produce the next username without having to produce all of them.

Community
  • 1
  • 1
Wes
  • 2,100
  • 1
  • 17
  • 31
  • +1 one for mentioning a generator. Though the iterable type doesn't really "contain" the items because they are yielded on demand and not actually stored. – jdi Jan 03 '13 at 03:51
  • Yeah, it's difficult to explain exactly how it works without bringing up lazy evaluation and such. I'll edit my answer to better reflect that. – Wes Jan 03 '13 at 03:51
  • Might want to add a snippet of example code -- using is generators much easier than understanding them :) – theodox Jan 03 '13 at 04:14
  • It returns the generator object. How can I yield all the elements? – user1881957 Jan 03 '13 at 04:16
2

When you call return, it autimtically exits out of the function, so it doesn't process anything after it reaches the return statement.

You might want to append the result to a list, then return the list.

In your case, you might even want to use a list comprehension, so instead of the for loop, use this:

return [row[0] for row in spamreader]
Volatility
  • 31,232
  • 10
  • 80
  • 89
1

You can only return once from a function. When it returns, it's over. The first time your function returns, it ends, so it only returns one value.

If you want to return all the values, accumulate them into a list and return the list.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 2
    'tis very annoying when you write an answer, and somebody else writes the exact same thing and submits his answer before you. – Volatility Jan 03 '13 at 03:47