Davi Magalhães
Davi Magalhães

Reputation: 75

Return key corresponding to the tuple with smallest third value from dictionary

I am trying to return the key corresponding to the tuple with smallest third index value from a dictionary of tuples (a namedtuple vertex as key and a tuple with 3 elements as value).

For example, suppose I have the tuple:

vertex = namedtuple("Vertex", ["vertex_id", "vertex_x", "vertex_y"])
d = {vertex(vertex_id='B', vertex_x=11, vertex_y=0): (4, 5, 9), 
        vertex(vertex_id='C', vertex_x=6, vertex_y=0): (2, 0, 2), 
        vertex(vertex_id='A', vertex_x=4, vertex_y=0): (0, 2, 3)}

I need something to return me Vertex(vertex_id='C', vertex_x=6, vertex_y=0). I was trying something like min(d.values(), key = lambda t: t[2]) (but this returns the tuple (2, 0, 2) and I would have to trace it back to its key) or min(d, key = lambda t: t[2]) (this isn't really working).

Is there a better way to set min() to do this or do I have to trace back the key corresponding to the value that the first way gives me? It would be more efficient if I don't have to search for it when working with larger dictionaries.

Upvotes: 2

Views: 384

Answers (3)

balderman
balderman

Reputation: 23815

If using a dict is not mandatory for you, I think the code below is the right way to go.
Anyway - you can see a modern NamedTuple example.

from typing import NamedTuple

class Vertex(NamedTuple):
  id:str
  x:int
  y:int

class Triple(NamedTuple):
  first:int
  second:int
  third:int

class Pair(NamedTuple):
  vertex: Vertex
  triple: Triple


pairs = [Pair(Vertex('B',11,0),Triple(4,5,9)),Pair(Vertex('C',6,0),Triple(2,0,2)),Pair(Vertex('A',4,0),Triple(0,2,3))]
_min = min(pairs,key=lambda p: p.triple.third)
print(_min.vertex)

Upvotes: 0

Andrej Kesely
Andrej Kesely

Reputation: 195543

Use min() with custom key= function. You can search the minimum over the tuples of d.items():

print( min(d.items(), key=lambda k: k[1][2])[0] )

Prints:

Vertex(vertex_id='C', vertex_x=6, vertex_y=0)

Upvotes: 1

General Poxter
General Poxter

Reputation: 554

Dictionaries are not intended to be used that way. You should not attempt to trace a value back to a key.
Try this instead:

keys = list(d.keys())
k = keys[0]
m = d[k]
for v in keys[1:]:
    if d[v][2] < m[2]:
        k = v
        m = d[k]

The vertex key you want will be in k.

Upvotes: 0

Related Questions