0

Is return better than yield? From what ive read it can be. In this case I am having trouble getting iteration from the if statement. Basically what the program does is take two points, a begin and end. If the two points are at least ten miles apart, it takes a random sample. The final if statement shown works for the first 20 miles from the begin point, begMi. nCounter.length = 10 and is a class member. So the question is, how can I adapt the code to where a return statement would work instead of a yield? Or is a yield statement fine in this instance?

def yielderOut(self):
    import math
    import random as r
    for col in self.fileData:
        corridor = str(col['CORRIDOR_CODE'])
        begMi = float(col['BEGIN_MI'])
        endMi = float(col['END_MI'])
        roughDiff = abs(begMi - endMi)

        # if the plain distance between two points is greater than length = 10
        if roughDiff > nCounter.length:
            diff = ((int(math.ceil(roughDiff/10.0))*10)-10)
            if diff > 0 and (diff % 2 == 0 or diff % 3 == 0 or diff % 5 == 0)\
               and ((diff % roughDiff) >= diff):

                if (nCounter.length+begMi) < endMi:
                    vars1 = round(r.uniform(begMi,\
                    (begMi+nCounter.length)),nCounter.rounder)
                    yield corridor,begMi,endMi,'Output 1',vars1

                if ((2*nCounter.length)+begMi) < endMi:
                    vars2 = round(r.uniform((begMi+nCounter.length),\
                    (begMi+ (nCounter.length*2))),nCounter.rounder)
                    yield corridor,begMi,endMi,'Output 2',vars1,vars2

So roughdiff equals the difference between two points and is rounded down to the nearest ten. Ten is then subtracted so the sample is taken from a full ten mile section; and that becomes diff. So lets say a roughDiff of 24 is rounded to 20, 20 - 10, diff + begin point = sample is taken from between mi 60 and 70 instead of between 70 and 80.

The program works, but I think it would be better if I used return instead of yield. Not a programmer.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 2
    There is a [great answer detailing *generators* in this thread](http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python) that you might want to check out. It might help clarify the difference for you. – Engineero Aug 06 '15 at 22:47
  • 1
    if you are reading a long csv file yield will save you memory when iterating over a sequence. – Jean Guzman Aug 06 '15 at 22:49
  • Yes it is a long csv file. I didn't include that part its up in the __init__ method above. Csv file parsing is mostly what I do with programs and they get quite large. –  Aug 06 '15 at 22:51

3 Answers3

6

return is not better, it's different. return says "I am done. Here is the result". yield says "here is the next value in a series of values"

Use the one that best expresses your intent.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Ok good explanation. But doesn't yield work differently with the system memory and such than return? Is one faster than the other? –  Aug 06 '15 at 22:46
  • I think then for my uses the next value in a series of values would be best for me. –  Aug 06 '15 at 22:49
1

Using yield makes your function a generator function, which means it will produce a series of values each time its (automatically created) next() method is called.

This is useful when you want to process things iteratively because it means you don't have to save all the results in a container and then process them. In addition, any preliminary work that is required before values can generated only has to be done once, because the generator created will resume execution of your code following the that last yield encountered — i.e. it effectively turns it into what is called a coroutine.

Generator functions quit when they return a value rather than yield one. This usually happens when execution "falls off the end" when it will return None by default.

From the looks of your code, I'd say using yield would be advantageous, especially if you can process the results incrementally. The alternative would be to have it store all the values in a container like a list and return that when it was finished.

martineau
  • 119,623
  • 25
  • 170
  • 301
0

I use yield in situations where I want to continue iteration on some object. However, if I wanted to make that function recursive, I'd use return.

nguyen
  • 71
  • 2