Search code examples
python-3.xfilterenumerate

Is it possible to chain iterators on a list in Python?


I have a list with negative and positive numbers:

a = [10, -5, 30, -23, 9]

And I want to get two lists of tuples of the values and their indexes in the original list so I did this.

b = list(enumerate(a))
positive = list(filter(lambda x: x[1] > 0, b))
negative = list(filter(lambda x: x[1] < 0, b))

But it feels kind of bad casting to list in between. Is there a way to chain these iterators immediately?


Solution

  • The iterator returned by enumerate can only be iterated once so that is why you have to cast it to a list or a tuple if you want to reuse the functionality of it multiple times.

    If you don't want to cast it or find that looping over the list twice is too inefficient for your liking you might want to consider a standard for loop, since it allows you to append to both lists at the same time in only a single iteration of the original list:

    a = [10, -5, 30, -23, 9]
    positive, negative = [], []
    for idx, val in enumerate(a):
      if val == 0:
        continue
      (positive if val > 0 else negative).append((idx, val))
    print(f"Positive: {positive}")
    print(f"Negative: {negative}")
    

    Output:

    Positive: [(0, 10), (2, 30), (4, 9)]
    Negative: [(1, -5), (3, -23)]