user9396820
user9396820

Reputation: 135

How to split a list of tuples based on the minimum value in each tuple?

Let's say I have a list of tuples (to make it easy I will just put 6 values in the example) like so:

x = [(1,2,3), (2,3,1), (0,10,100), (4,0,5), (2,1,3), (3.3,9,1.2), (4.5,2,0), (2,4,10), (100, 10, 30)]

The list x is a list of tuples, each tuple has 3 values so only 3 indexes.

What I want is to split the list x into 3 lists, the first list has the minimum value in the tuple at the first index, the second list has the minimum value in the tuple at the second index, the 3rd list has the minimum value of the tuple at the 3rd index. Basically, I need to enter each tuple see where the minimum value is (at which index) and the put the tuple in the sub-list in which it belongs.

So I would have as result:

x1 = [(1,2,3), (0,10,100), (2,4,10)]
x2 = [(4,0,5), (2,1,3), (100, 10, 30)]
x3 = [(2,3,1), (3.3,9,1.2), (4.5,2,0)]

Upvotes: 1

Views: 492

Answers (6)

Tomerikoo
Tomerikoo

Reputation: 19422

You can do this with no imports and a single pass on the input list.

  • Initialize the result list with three empty sublists.
  • Pass over each tuple, and append it to the sublist in the matching index of the minimum element in the tuple.
  • In the end, each sublist will contain the tuples whose minimum element is in the same index as the sublist:
x = [(1,2,3), (2,3,1), (0,10,100), (4,0,5), (2,1,3), (3.3,9,1.2), (4.5,2,0), (2,4,10), (100, 10, 30)]

mins = [[], [], []]
for tup in x:
    mins[tup.index(min(tup))].append(tup)

print(mins)

Will give:

[[(1, 2, 3), (0, 10, 100), (2, 4, 10)],    # mins[0] - tuples with minimum in index 0
 [(4, 0, 5), (2, 1, 3), (100, 10, 30)],    # mins[1] - tuples with minimum in index 1
 [(2, 3, 1), (3.3, 9, 1.2), (4.5, 2, 0)]]  # mins[2] - tuples with minimum in index 2

Upvotes: 0

theunknownSAI
theunknownSAI

Reputation: 330

def meth(a):
    if a[0] < a[1] and a[0] < a[2]:
        return 1
    if a[0] > a[1] and a[0] < a[2]:
        return 0
    return -1
x = sorted(x, key=meth)
print(x[:3])
print(x[3:6])
print(x[6:9])

Upvotes: 0

elaaf
elaaf

Reputation: 81

You can easily do this using list comprehension:

abc = [(1,2,3), (2,3,1), (0,10,100), (4,0,5), (2,1,3), (3.3,9,1.2), (4.5,2,0), (2,4,10), (100, 10, 30)]


x1 = [x for x in abc if x.index(min(x))==0]
x2 = [x for x in abc if x.index(min(x))==1]
x3 = [x for x in abc if x.index(min(x))==2]

print(x1)
print(x2)
print(x3)

Output:
[(1, 2, 3), (0, 10, 100), (2, 4, 10)]
[(4, 0, 5), (2, 1, 3), (100, 10, 30)]
[(2, 3, 1), (3.3, 9, 1.2), (4.5, 2, 0)]

Upvotes: 0

Chris
Chris

Reputation: 29742

One way using collections.defaultdict:

from collections import defaultdict

d = defaultdict(list)

def argmin(arr):
    return min(range(len(arr)), key=lambda x: arr[x])

for t in x:
    d[argmin(t)].append(t)

Or using numpy.argmin:

for i, t in zip(np.argmin(x, 1), x):
    d[i].append(t)
    

Output:

defaultdict(list,
            {0: [(1, 2, 3), (0, 10, 100), (2, 4, 10)],
             2: [(2, 3, 1), (3.3, 9, 1.2), (4.5, 2, 0)],
             1: [(4, 0, 5), (2, 1, 3), (100, 10, 30)]})

Upvotes: 0

CutePoison
CutePoison

Reputation: 5365

You can simply just do it in a loop:

import numpy as np
x = [(1,2,3), (2,3,1), (0,10,100), (4,0,5), (2,1,3), (3.3,9,1.2), (4.5,2,0), (2,4,10), (100, 10, 30)]
Xs = {0:[],1:[],2:[]} #For indexing 


for t in x:
    idx = np.argmin(t)
    Xs[idx].append(t)

x1 = Xs[0]
x2 = Xs[1]
x3 = Xs[2]

Upvotes: 0

Rustam Garayev
Rustam Garayev

Reputation: 2692

List comprehension with simple check could give you desired output:

x = [(1,2,3), (2,3,1), (0,10,100), (4,0,5), (2,1,3), (3.3,9,1.2), (4.5,2,0), (2,4,10), (100, 10, 30)]

x1 = [i for i in x if i[0] == min(i)]
x2 = [i for i in x if i[1] == min(i)]
x3 = [i for i in x if i[2] == min(i)]

Upvotes: 2

Related Questions