4

I have a list of lists say E[ ][ ], where E has ten sub-lists, each having around 500 entries.

My prime concern is to calculate the maximum of all the 5000 values, which are distributed in ten sub-lists.

Now, what I wrote was this:

MinVal = min(min(E[i]) for i in range(len(E)))

and it gave me this error: ValueError: min() arg is an empty sequence

Now I wrote this:

min_arr = []
for i in range(len(E)):
    min_arr.append(min(E[i]))
MinVal = min(min_arr)

and it gives me the same error: ValueError: min() arg is an empty sequence

So, I just try out doing this:

print(max(E[1]))

and it DOES give me the answer

The first two codes also work for small 5-10 element lists. But shows an issue with large data sets.

What should I do?

Community
  • 1
  • 1
complextea
  • 393
  • 1
  • 5
  • 16
  • 1
    Will you please give sample date for `E` ? – Nilesh Aug 05 '14 at 10:21
  • 1
    Why not just `min(min(e) for e in E if e)`? You don't really need the index `i`, and this will skip empty sub-lists (you'll only get an error if *all* sub-lists are empty, in which case `min` has no meaning anyway). – jonrsharpe Aug 05 '14 at 10:22
  • Built-in functions don't just break mysteriously just because you give them large amounts of data. One of the `min` calls gets an empty sequence as argument, you just have to sift through your large data set and find it. We can't help you with that. –  Aug 05 '14 at 10:25
  • @jonrsharpe Hey, that worked! Would you please be able to explain why this worked and why mine didn't? – complextea Aug 05 '14 at 10:29
  • @delnan I guess, it just encountered an empty sequence then? Ok. I'll look for that. – complextea Aug 05 '14 at 10:31
  • @jonrsharpe Hey, I find your solution perfect. Why don't you write it as the main answer, I'll accept it. What is the difference between your answer and this: MinVal = min(i for sublist in E for i in sublist) – complextea Aug 05 '14 at 10:50
  • @HobbitEesmereldatGoldworthy what do you mean *"what is the difference"*? They do the task in slightly different ways. I will leave you to experiment and find out more! – jonrsharpe Aug 05 '14 at 10:52
  • @jonrsharpe Yeah. Thanks once again. – complextea Aug 05 '14 at 10:53
  • Does this answer your question? [min() arg is an empty sequence](https://stackoverflow.com/questions/27114738/min-arg-is-an-empty-sequence) – AMC Feb 22 '20 at 02:09

2 Answers2

4

Your code:

MinVal = min(min(E[i]) for i in range(len(E)))

fails when E[i] == [], as there is no sensible definition of the minimum of an empty set. You therefore need to skip empty sub-lists. One option would be:

min_val = min(min(e) for e in E if e)

which is roughly equivalent to:

min_vals = []
for e in E:
    if e: # or 'if e != []:' - empty sequences evaluate False-y
        mins.append(min(e))
min_val = min(min_vals)

(Note that you're not actually using the index i anywhere, so you can iterate directly over E.)

5,000 items isn't that many, you probably don't need to worry too much about efficiency.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
1

You want to use a generator expression flattening your lists by nesting loops:

MinVal = min(i for sublist in E for i in sublist)

Your error indicates that at least one of your sublists is empty, but the above naturally skips such empty sublists.

If you need to determine both the minimum and maximum, don't use two loops. Use one loop and track minimum and maximum values 'manually':

minimum = float('inf')
maximum = float('-inf')
for sublist in E:
    for i in sublist:
        if i < minimum:
            minimum = i
        if i > maximum
            maximum = i

This ensures you only loop once over the large number of values.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks, I didn't know about the 'sublist' thingy. Though, the answer given by @jonrsharpe is also right. Does using 'sublist' make it a complicated solution? Or maybe slower? Or would you like to elaborate the difference between your answer and min(min(e) for e in E if e)? – complextea Aug 05 '14 at 10:38
  • @HobbitEesmereldatGoldworthy: I'll add a `timeit` comparison; it is hard to say which one will be faster here as this depends on the number of sublists and the average number of elements in those sublists. – Martijn Pieters Aug 05 '14 at 10:59
  • @HobbitEesmereldatGoldworthy: I got called away for something else; for your usecase, using nested `min()` calls, as jonrsharpe does, is faster here, as those calls get to iterate over the sublists using a C loop. – Martijn Pieters Aug 05 '14 at 11:56
  • @HobbitEesmereldatGoldworthy: You need a *lot* of small sublists to make the cost of calling another function cost more than the speed gain. – Martijn Pieters Aug 05 '14 at 11:57