0
def miniMaxSum(arr):
    #
    # Write your code here.
    #
    eArr = enumerate(arr)
    maxNum = 0
    indexMax = -1;
    for a,b in eArr:
        if b > maxNum:
            maxNum = b
            indexMax = a

    for index,number in eArr:
        print("hello")

why does it not print anything? I put the print hello part to see if it iterates through the second for loop.

6
  • What is the value of arr? Commented Apr 5, 2018 at 6:06
  • enumerate is an iterator. Iterators can only be used once; after that, they're empty. Commented Apr 5, 2018 at 6:06
  • eArr is an enumerate object: an iterator, not a list. You already consumed all generated data in the first loop. There is nothing left for the second loop. Solution: convert the iterator to a list eArr = list(enumerate(arr)). Commented Apr 5, 2018 at 6:07
  • it's just a list of numbers 1 to 5. the first loop works but the second doesn't Commented Apr 5, 2018 at 6:07
  • No, it is not a list. But you can make it a list. Commented Apr 5, 2018 at 6:08

1 Answer 1

5

enumerate is an iterator. Iterators can only be used once; after that, they're empty.

The easy (and idiomatic) solution is to just make a new enumerate iterator for each loop:

def miniMaxSum(arr):
    maxNum = 0
    indexMax = -1;
    for a,b in enumerate(arr):
        if b > maxNum:
            maxNum = b
            indexMax = a

    for index,number in enumerate(arr):
        print("hello")

If you need to use an iterator more than once, you can save it to a list, and then reuse the list. Just change this line

eArr = enumerate(arr)

… to this:

eArr = list(enumerate(arr))

In this case, there's no reason to do that. You'd just be wasting memory building the list. (As for speed, it's probably a little faster for very small lists, but slower for very big ones—but it probably doesn't matter either way for your code.) But there are cases where it's useful, so it's worth knowing how to do.

Sign up to request clarification or add additional context in comments.

6 Comments

In the OP's example, the iterator in fact is used twice, so there may be a reason to convert it to a list. Constructing the list takes time, but calling the iterator's next() at each iteration also takes time.
@DyZ I highly doubt that performance actually matters here unless the input list is huge—and if it is, the allocation costs are going to hurt a lot more than iterating twice. According to a quick %timeit test, two enumerates are significantly faster than a list and two iteration once you get into the millions, and they're never more than 2x as slow even for tiny lists. An optimization that saves less than 1us for some cases and wastes more than 1ms for others is not generally worth doing.
What are the "cases where it's useful", then?
@DyZ Needing to access the values in reversed or random-access order, needing to pass them to a function that demands a sequence for some reason, needing to use it tons of times instead of just twice, as a micro-optimization in the very rare cases where you've found a bottleneck doing it twice and tested both ways on your actual data… If you run into a case where it's useful, you'll generally know it.
@DyZ Do you think the answer needs to explain any of that? My thought was that it will just be unnecessary information, and possibly overwhelming, to the OP, or to someone else with the same question, but I could easily be wrong on that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.