Find minimum of absolute of second value in a subset of tuples in a list of tuples (python)

Viewed 71

I have a list of tuples:

list = [(1,-1),(1,1),(2,0),(3,-9),(3,9),(4,-10),(4,-8),(4,8),(4,10),(5,-25),(5,25),(5,-9),(5,9)]

Here is what I want to do:

  • For every number in the first place, i.e. for 1, 2, 3, 4, and 5, find the minimum of abs(second value). If there are multiple minima, find all of them. For instance, for '1' in the first place both (1,-1) and (1,1) qualify because abs(-1)=abs(1)
  • Create another list with 1s in corresponding places where the tuples in the list qualify and 0 where they do not. The answer is [1,1,1,1,1,0,1,1,0,0,0,1,1]

Here is my code:

result=[]
temp_first=list[0][0]
temp_second=abs(list[0][1])
result.append(1)
for element in list[1:]:
    if element[0]==temp_first:
        if abs(element[1])<temp_second:
            result[-1]=0
            result.append(1)
        elif abs(element[1])>temp_second:
            result.append(0)
        else:
            result.append(1)          
    else:
        result.append(1)
        
    temp_first=element[0]
    temp_second=abs(element[1])        

It gives me [1,1,1,1,1,0,1,1,0,1,0,1,1] which is incorrect

Any help will be appreciated

2 Answers

Try:

lst = [
    (1, -1),
    (1, 1),
    (2, 0),
    (3, -9),
    (3, 9),
    (4, -10),
    (4, -8),
    (4, 8),
    (4, 10),
    (5, -25),
    (5, 25),
    (5, -9),
    (5, 9),
]

tmp = {}
for a, b in lst:
    tmp.setdefault(a, []).append(abs(b))
tmp = {k: min(v) for k, v in tmp.items()}

out = [int(abs(b) == tmp[a]) for a, b in lst]
print(out)

Prints:

[1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1]

Something like so I think makes the most sense:

output = []

# Iterate through the indexes (1, 2, 3, 4, 5).
for index in {tpl[0] for tpl in lst}:

    # Filter index-specific tuples [(1, -1), (1, 1)]
    index_list = list(filter(lambda tpl: tpl[0] == index, lst))

    # Get tuple with the smallest item (1, -1)
    smallest_in_list = min(index_list, key=lambda tpl: abs(tpl[1]))

    # Absolute value of the second number.
    smallest_item_in_list = abs(smallest_in_list[1])

    # Creates output list for current iteration.
    iter_output = [1 if abs(tpl[1]) == smallest_item_in_list else 0 for tpl in index_list]

    output.extend(iter_output)
Related