0

I've three sample input lists of tuples:

bc_lst = [(639, 16), (653, 25), (734, 33), (768, 50), (777, 16), (827, 42), (854, 24), (867, 63), (869, 48), (877, 26), (903, 26), (927, 26), (929, 22), (949, 20), (969, 20), (990, 19), (999, 23), (1010, 19), (1030, 20), (1042, 63), (1049, 20), (1069, 17), (1143, 18), (1158, 18), (1174, 25)]

uc_lst = [(1215, 25), (1293, 25), (1317, 29), (1327, 43), (1346, 26), (1374, 26), (1400, 21), (1420, 21), (1430, 102), (1443, 20), (1465, 19), (1486, 20), (1506, 21), (1528, 20), (1549, 20), (1570, 20), (1591, 20), (1612, 16), (1621, 26), (1632, 21), (1639, 26), (1653, 21)]

dt_lst = [(1566, 39), (1609, 24), (1620, 20), (1650, 38), (1658, 20), (1691, 37), (1701, 20), (1732, 38), (1772, 16), (1785, 19), (1814, 36), (1854, 37), (1854, 38), (1861, 19)]

and a buffer variable buf = 5. I want to do this operation on bc_lst, uc_lst and dt_lst : check from the first item, if the sum of the tuple is less than the sum of the first element of the next tuple and the buffer then remove the next item from the list and check for the next list item.

Consider bc_lst. Sum of first tuple is 655 and 653+5 > 655, so we keep (653,25). Now check whether 734 +5 > 653+25, which is True so keep the (734,33). Now check 768 +5 > 734+33, which is again True, so we check for the next item but 777 +5 > 768+50 is False, so we drop the tuple (777,16). Now we again check if 827+5 > 768+50 which is True, so we keep (827,42). The process goes on.

This is the code I tried :

def func1(a1):
    count = 0
    while count < len(a1)-1:
        if a1[count+1][0] + buf < sum(a1[count]):
            del a1[count+1]
        count +=1
func1(bc_lst)

The output I get for bc_lst is :

[(639, 16), (653, 25), (734, 33), (768, 50), (827, 42), (867, 63), (877, 26), (903, 26), (927, 26), (949, 20), (969, 20), (990, 19), (1010, 19), (1030, 20), (1049, 20), (1069, 17), (1143, 18), (1158, 18), (1174, 25)]

, for uc_lst the output is :

[(1215, 25), (1293, 25), (1317, 29), (1346, 26), (1374, 26), (1400, 21), (1420, 21), (1443, 20), (1465, 19), (1486, 20), (1506, 21), (1528, 20), (1549, 20), (1570, 20), (1591, 20), (1612, 16), (1632, 21), (1653, 21)]

, for the dt_lst the output is :

[(1566, 39), (1609, 24), (1650, 38), (1691, 37), (1732, 38), (1772, 16), (1785, 19), (1814, 36), (1854, 37), (1861, 19)]

Whereas, the desired output for bc_lst is :

[(639, 16), (653, 25), (734, 33), (768, 50), (827, 42), (867, 63), (927, 26), (949, 20), (969, 20), (990, 19), (1010, 19), (1030, 20), (1049, 20), (1069, 17), (1143, 18), (1158, 18), (1174, 25)]

, the desired output for uc_lst is same as the output I get and the desired output for dt_lst is :

[(1566, 39), (1609, 24), (1650, 38), (1691, 37), (1732, 38), (1772, 16), (1814, 36), (1854, 37)]

What's wrong in the code?

Arkistarvh Kltzuonstev
  • 6,824
  • 7
  • 26
  • 56
  • Possible duplicate of [python doesnt remove all the items from a list while iterating over the list](https://stackoverflow.com/questions/54846323/python-doesnt-remove-all-the-items-from-a-list-while-iterating-over-the-list) – Aemyl Feb 28 '19 at 06:54
  • `itertools.compress` is probably what you want here – Aemyl Feb 28 '19 at 06:54
  • @Aemyl It's not duplicate, the logic behind removing the items from the list while iterating over the list is different for my question. – Arkistarvh Kltzuonstev Feb 28 '19 at 06:57
  • 1
    `itertools.compress` should still work here. Should I write an example as an answer? – Aemyl Feb 28 '19 at 06:59
  • Ok, I guess Mike Robins has answered this question well and shown that `itertools` is not needed here. – Aemyl Feb 28 '19 at 07:13

2 Answers2

2

I think the problem is that if you remove an item, you don't want to increment count.

buf=5

def func1(a1):
    count = 0
    while count < len(a1) - 1:
        if a1[count + 1][0] + buf < sum(a1[count]):
            del a1[count + 1]
        else:
            count += 1
Mike Robins
  • 1,733
  • 10
  • 14
2

To save intermediate results you can process elements one by one.

For example, you will have a function with input as a list you want to process, buffer, and current processing element index like this:

def process_list_element(list, current_index, buffer):
    if list[current_index + 1][0] + buf < sum(list[current_index]):
        del list[current_index+ 1]
    else:
        current_index += 1
    return list, current_index

* Please look carefully as it's just pseudocode to demonstrate the approach

And then just repeat

index = 0
buffer = 5
while index < len(list) -1:
    list, index = process_list_element(list, index, buffer)
Arkistarvh Kltzuonstev
  • 6,824
  • 7
  • 26
  • 56
Platon
  • 84
  • 2