-1

I have a 2D list of lists in Python and I need to find the lowest float in column 1, and then return the value in the same row, but at column 0.

mylist =  [['someid-1', None] ,['someid-2', 4545.474] ,['someid-3', 200.1515] ,['someid-4', None] ,['someid-4', 0]]

In this case I want returned: someid-3

At the moment I am appending only values which are not None and then do this: (which seems complicated for such a "simple" task)

    mylist.sort(key=lambda x: x[1])
    if len(temp_op_distance_list) != 0 and temp_op_distance_list[0][1] != None:
        return temp_op_distance_list[0][0]

Some info on the overall Python project.

The list is about 8000 entries with values 'None' and some floats. This code collects distance to a Mousepointer in 3D space and test all 3D objects in the Programm. When there is the value None the object was not hit.

Edited: Proper list formatting - Of course you all are right, pointing out that my list is not correct. Sorry about that.

AndyG
  • 39,700
  • 8
  • 109
  • 143
mogh
  • 3
  • 1
  • 4
  • How is `200.1515` lower than `0`? And besides, that's not a legal Python list, (`[someid-1][None]` is not a list with two elements) such that it's unclear what you mean or what structure your list actually is. Can you show an example of a list that can evaluate in Python, something like `[[1, 5], [3, 12], [5, -3]]`? And is that the kind of list you mean? – David Robinson Feb 21 '13 at 16:51
  • Your lists are not formatted correctly, you probably meant `[someid_1, None],`, etc. – Martijn Pieters Feb 21 '13 at 16:57

2 Answers2

1

Assuming your list is a proper Python List

mylist =  [['someid-1', None] ,['someid-2', 4545.474] ,['someid-3', 200.1515] ,['someid-4', None] ,['someid-4', 0]]

You can simply create a generator expression, selecting only the Valid Non Zero Items and determine the min using the key as itemgetter(1)

>>> from operator import itemgetter
>>> min((e for e in mylist if e[1]), key = itemgetter(1))[0]
'someid-3'
Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • My head is not operating at proper efficiency levels. Of course `min()` makes more sense.. – Martijn Pieters Feb 21 '13 at 17:03
  • thanks to all of you for the answers already, I will test the code tomorrow. – mogh Feb 21 '13 at 22:12
  • May I ask an additional question? What to do if the list cotains only: `mylist = [['someid-1', None] ,['someid-2', None]]` min throws me an error that the `min() arg is an empty sequence` kind regards – mogh Feb 24 '13 at 16:07
  • found a solution here [http://stackoverflow.com/questions/15036763/what-is-the-pythonic-way-to-access-nested-dicts-without-nonetype-errors](http://stackoverflow.com/questions/15036763/what-is-the-pythonic-way-to-access-nested-dicts-without-nonetype-errors) of course changing tne `KeyError to ValueError` - regards mogh – mogh Feb 26 '13 at 13:54
0

Combine filtering with min():

from operator import itemgetter

id = min(filter(itemgetter(1), mylist), key=itemgetter(1))[0]
  • The filter(itemgetter(1), mylist) removes all elements whose second element is falsey; False in a boolean context. That includes 0 and None.

  • min(..., key=itemgetter(1)) finds the lowest value based on the key you give it; so the list with the lowest float value after filtering.

  • [0] selects the id entry from your list.

A quick demo (with a syntactically correct input list):

>>> mylist = [
...     ['someid-1', None], 
...     ['someid-2', 4545.474], 
...     ['someid-3', 200.1515], 
...     ['someid-4', None], 
...     ['someid-5', 0]
... ]
>>> from operator import itemgetter
>>> min(filter(itemgetter(1), mylist), key=itemgetter(1))[0]
'someid3'
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343