-2

Hello please how can I use the each elements in the list 'trav_time' twice for two different calculations in the evaluate_routes function for each each time cs loops. It works well for fit but gives the error below for fit1. Thank you

trav_time = iter([3,6,7,9,11])
value_of_time = 15
trnsfr_pen = 0.21

def evaluate_routes():

    fitness = []
    fitness1 = []

    for cs in range(5):

        fit = (trav_time.next() * (5 /  trnsfr_pen) * value_of_time)

        fitness.append(fit)

        fit1 = trav_time.next() * 3

        fitness1.append(fit1)


    print "fitness: ",fitness
    print
    print "fitness: ",fitness1

    return fitness

evaluate_routes()

Traceback (most recent call last):
  File "C:/Users/AMAMIFE/Desktop/obi/hey.py", line 251, in <module>
    evaluate_routes()
  File "C:/Users/AMAMIFE/Desktop/obi/hey.py", line 240, in evaluate_routes
    fit1 = trav_time.next() * 3
StopIteration
Nobi
  • 1,113
  • 4
  • 23
  • 41

2 Answers2

3

You're incorrect. This code doesn't work for fit or fit1, and it's because you're calling next twice. Every time you call next, it fetches the next element. This means you're fetching 2 different elements per iteration. You need to modify your code so that you only fetch one element per loop iteration. I'll leave figuring out how to only fetch a single time as an exercise for you; it's well within your ability. Just think about it a bit.

In real world code, you almost never actually need to call next directly. You generally find some way of looping without it, such as using a loop or generator.

Last, the code you posted is not the code that produces the error you're experiencing. The code you posted would cause an AttributeError: 'list' object has no attribute 'next'. (OP fixed the typo.)

jpmc26
  • 28,463
  • 14
  • 94
  • 146
  • thanks for your thoughts, it was a typo, I have edited it trav_time = iter([3,6,7,9,11]). Is there then a way to use the elements in that list twice? Thanks – Nobi May 08 '14 at 09:02
  • @Nobi Yes, there's lots of ways. Here's a hint toward the simplest. You can only call `next` once. How can you use a value more than once without repeating it? How are you reusing the same `fitness` and `fitness1` lists without creating new ones all the time, or how are you avoiding typing `0.21` multiple times for the "transfer pen" in your code? I'm specifically avoiding actually writing the code for you; I think you'll benefit much more from working it out yourself. – jpmc26 May 08 '14 at 09:11
  • 1
    thanks, I did this temp = trav_time.next(), and I can then use temp multiple times. Thanks for your approach of letting me try to solve the problem myself but with your hints. I appreciate and if there are other helpful points about this kindly drop them. I only started programming in python few weeks back so I still find a few things hard. – Nobi May 08 '14 at 09:29
  • @Nobi Yes, that's exactly what I had in mind. =) We were all new once, and we all found (and frankly, still find) things confusing. For this particular problem, I think I would need to know a lot more about the whole problem to make any real recommendations for how I would write the code. There's really only a couple of pieces of advice I would give in all situations: always try to break up your code into very short pieces of logic, work very hard at naming things so clearly that any idiot will understand them, and never blindly rely on any process or practice. – jpmc26 May 08 '14 at 10:12
  • Good answer, but I don't agree that `next` rarely is called explicitly. I use it all the time. Skipping a header in a text file is a good example. – Steinar Lima May 08 '14 at 16:30
  • @SteinarLima Maybe I should restrict my comment to "inside a loop", then? I can see a one off thing where you need to skip an element or what have you, but you pretty much never need to do the iterating yourself. Although, even with one off stuff, you could use `itertools` (such as `islice`, as mentioned [here](http://stackoverflow.com/a/16800855/1394393)). – jpmc26 May 08 '14 at 21:55
  • @jpmc26 I don't agree with you there either. There's a lot of use cases even inside loops :) – Steinar Lima May 08 '14 at 23:00
  • @SteinarLima There's a lot of places where you *could* use `goto`, but that doesn't make it a good idea. If you find yourself manually manipulating iterators very frequently in Python, then I would say you are either building iterators or need to step back and see if you can solve your problems more simply and clearly. Python gives you loads of tools to avoid doing those kinds of things yourself; make heavy use of them. – jpmc26 May 14 '14 at 04:56
2

In Python you can loop through each item in a list like so:

trav_time = [3,6,7,9,11]
value_of_time = 15
trnsfr_pen = 0.21

def evaluate_routes():

    fitness = []
    fitness1 = []

    for item in trav_time:
        fit = (item * (5 /  trnsfr_pen) * value_of_time)
        fitness.append(fit)
        fit1 = item * 3
        fitness1.append(fit1)

    print "fitness: ",fitness
    return fitness

evaluate_routes()

Saves you having to hardcode a loop with a value you dont use

Martyn
  • 806
  • 1
  • 8
  • 20
  • that works but not what i want. for cs in range(5) is needed specifically. Thanks – Nobi May 08 '14 at 08:40
  • @Nobi Why do you need it? Why are you using `next()`? – sloth May 08 '14 at 08:47
  • its because this is just a snippet out of the real problem I'm working on. The hard coded loop range(5), should denote another list that I am to work with inside the function. But its a lot of codes and I don't know if I paste that on the forum, if i will get attention for it – Nobi May 08 '14 at 08:59
  • Can you not just loop through that other list aswell? Or use a counter inside the loop? – Martyn May 08 '14 at 09:12