Understanding python policy to find minimum in list list

I have the following list of value lists, and I want to find the min value among all the values.

Q = [[8.85008011807927, 4.129896248976861, 5.556804136197901], [8.047707185696948, 7.140707521433818, 7.150610818529693], [7.5326340018228555, 7.065307672838521, 6.862894377422498]] 

I planned to do something like:

 min(min(Q)) 

I tried this approach with a smaller example and it works:

 >>>b = [[2,2],[1,9]] >>>min(b) [1, 9] >>>min(min(b)) 1 

But using this in my original Q list, it returns an incorrect result:

 >>> min(Q) [7.5326340018228555, 7.065307672838521, 6.862894377422498] >>> min(min(Q)) 6.862894377422498 

Why is this approach wrong and why?

+6
source share
9 answers

Lists are compared using lexicographic order 1 (i.e., the first elements are compared, then the second, then the third, etc.), therefore simply because list_a < list_b does not mean that the smallest element in list_a smaller than the smallest element in list_b , therefore your approach does not work in the general case.

For example, consider the following:

 >>> l1 = [3, 0] >>> l2 = [2, 1] >>> >>> min(l1, l2) [2, 1] 

The reason for min(l1, l2) is [2, 1] , because the first element l1 ( 3 ) is initially compared with the first element l2 ( 2 ). Now 2 < 3 , so l2 returns at least without any additional comparisons. However, it l1 does contain the smallest number from both lists ( 0 ) that occurs after the starting element. Therefore, taking min of min(l1, l2) , we get the wrong result 1 .

A good way to solve this problem would be to find the minimum "flattened" list that can be obtained using the generator:

 >>> Q = [[8.85008011807927, 4.129896248976861, 5.556804136197901], ... [8.047707185696948, 7.140707521433818, 7.150610818529693], ... [7.5326340018228555, 7.065307672838521, 6.862894377422498]] >>> >>> min(a for sub in Q for a in sub) # <-- 4.129896248976861 

(+ 1 to @Ffisegydd for posting a decision on these lines in the first place.)


1 From http://docs.python.org/3/tutorial/datastructures.html#comparing-sequences-and-other-types :

Sequence objects can be compared with other objects with the same type of sequence. The comparison uses lexicographical ordering: first, the first two elements are compared, and if they differ from each other, this determines the result of the comparison; if they are equal, the following two elements are compared, and so on, until any sequence is exhausted. If the two elements to be compared are themselves sequences of the same type, the lexicographic comparison is performed recursively. If all elements from two sequences are compared equal, the sequences are considered equal. If one sequence is the initial subsequence of another, the shorter sequence is the smaller (smaller) one.

+7
source

Your approach didn’t work as it should because

sequence comparison

I want to find the value of min among all the values.

If you want to find the minimum of all values, you can do something like this

 print min(map(min, Q)) # 4.12989624898 
+3
source
+3
source

min(map(min,Q)) ist the command you are looking for.

+1
source
  • min(Q) returns the "minimum" list in Q , which is a list with the smallest first element.
  • Therefore min(min(Q)) returns the smallest element of the list with the smalles first element, which is not what you want.

you can use

 min(min(x) for x in Q) 

which returns the smallest of the minima of all lists in Q

+1
source

What you really want is to flatten this list and then find the minimum:

 min(value for row in Q for value in row) 
+1
source

There are many answers, but the simplest way IMHO is to β€œlist the lists” into a single list using itertools.chain.from_iterable :

 from itertools import chain min(chain.from_iterable(Q)) 

or a shorter and equally easy to read (to me) version:

 min(chain(*Q)) 
+1
source

I think I found why, min, applied to a list of lists, compares the first values ​​of each sublist.

 >>> b=[[3,1],[2,5]] >>> min(b) [2, 5] 
0
source

min (Q) does not always return a list that should contain a minimum of all values. That is why your approach is wrong. You must find the min value for the entire list and make another list. then find the min of this list that it is.

0
source

All Articles