0
ret = []
sub_total = 0
        for peak, value in zip(list_1, list_2):
            sub_total += value
            if sub_total >= mid_rule:
                # print(sub_total)
                ret.append(peak)         
                break

My main goal is optimisation because this code takes a lot of memory resources;

I have tried this;

ret = [peak if (sub_total :=0 + value) >= mid_rule for peak, value in zip(min_idx, min_count)]

but not yielding any results; your help is much appreciated

  • Do the answers to this [question](https://stackoverflow.com/questions/9572833/using-break-in-a-list-comprehension) help at all? – quamrana May 22 '22 at 15:56
  • It would be helpful if you created a code example that defined all the names and included the result you want in the end. It looks like your code creates a list with one value, but it's not clear why you would need a list for that. – Mark May 22 '22 at 16:03
  • Why do you need a list? Have you considered making it a generator instead, so it never has to store all the intermediary values, but rather presents them only when needed? Also ... what is mid_rule? – Kenny Ostrom May 22 '22 at 16:08

2 Answers2

1

This may convert what you had into a list comprehension, but to better optimize your code we need to know why you are doing things as @Kenny Ostrom and @Mark mentioned.

sub_total = 0
ret = [peak for peak, value in zip(list_1, list_2) if (sub_total := sub_total + peak) >= mid_rule]

your if statement in the list comprehension seemed incorrect in your example and that you were doing 0 + peak when it should be subtotal + peak in your other example.

Taking @Jerome Richard's suggestion you could do:

ret = []
sub_total = 0
for peak, value in zip(list_1, list_2):
    sub_total += value
    if sub_total >= mid_rule:
        yield peak

and can make a generator comprehension like

sub_total = 0
ret = (peak for peak, value in zip(list_1, list_2) if (sub_total := sub_total + peak) >= mid_rule)

Though it seems strange to create a list object only to use a single item before the break ~ you could remove having it as a list which would save you very little time. But again we need to know what is occurring to further optimize your code.

Source

Andrew Ryan
  • 1,489
  • 3
  • 15
  • 21
  • 2
    Note the OP used a break so there is no need to iterate on all values (which an be far more expensive regarding the target case). You can replace the list comprehension by a simple generator and get just one item (if any). – Jérôme Richard May 22 '22 at 17:30
0

i'm a little late to this but probably the easiest way is a gen exp with some itertools functionality

from itertools import accumulate

ret = next(
    (peak for peak, running_total in zip(list_1, accumulate(list_2)) if running_total >= mid_rule),
    None,
)
acushner
  • 9,595
  • 1
  • 34
  • 34