3

Trying to remove min and max values from two dimensional list in array. My code:

myList = [[1, 3, 4], [2, 4, 4], [3, 4, 5]]
maxV = 0
minV = myList[0]0]
for list in myList:
   for innerlist in list:
      if innerlist > maxV:
         maxV = innerlist
      if innerlist < minV:
         minV = innerlist
   innerlist.remove(maxV)
   innerlist.remove(minV)
print(myList)

This causes me some erros, which i not particulary understand. I'm quite sure that innerlist is not array but ordinary variable. But still i think it should be somehow possible to remove min and max elements from two dimensional list. I mean I need to remove in every innerlist in my list highest and lowest values. LF help! Regards.

Karolis Šiaulys
  • 117
  • 3
  • 10
  • What about duplicates? For instance, should the middle list be empty after the operation since there are 2 "high" values? – Brendan Abel Mar 25 '16 at 16:59
  • 1
    `innerlist` is not a list; it's an integer. `myList` and `list` are the only lists you have. – C_Z_ Mar 25 '16 at 16:59

5 Answers5

11

Just for the sake of showing a much simpler way of doing this using list comprehensions, the sorted method and slicing:

d = [[1, 3, 4], [2, 4, 4], [3, 4, 5]]

n = [sorted(l)[1:-1] for l in d]

print(n)

# [[3], [4], [4]]

Some reading material on each of the items used to solve this problem:

To take care of duplicates, this answer by Padraic is very well done.

Community
  • 1
  • 1
idjaw
  • 25,487
  • 7
  • 64
  • 83
  • 2
    But 4 is equal to the max – Padraic Cunningham Mar 25 '16 at 17:01
  • Thanks a lot! Just one more things if my array begins with string element, and i've already have read about sorting, i know that (lets say have list _d = [["xa",1, 3, 4], ["la",2, 4, 4], ["ta",3, 4, 5]]_) _n = [sorted(l)[2:-1] for l in d]_ should take from the second element in array but still it messes me with error, seems he still tries to sort string :( – Karolis Šiaulys Mar 25 '16 at 17:30
  • @KarolisŠiaulys, you are slicing the sorted list no the original list, if the. 2:-1 also starts at the third not the second, in python2 the string will get sorted to the end of the list so you still have the max when you `sorted(l)[2:-1] ` and lose the two lowest ints, if you want to remove the string and the max use `sorted(l)[1:-2]`, you should also be aware that sorting or any comparison using python 3 will cause an `unorderable types` error as you cannot compare a string to an int – Padraic Cunningham Mar 25 '16 at 20:17
3

If you want to remove all occurrences, you will have to find the min and max and remove all occurrence from each sublist:

def remove(l):
    for sub in l:
        t = {min(sub), max(sub)}
        sub[:] = (ele for ele in sub if ele not in t)


l = [[1, 3, 4], [1, 2, 4, 4], [3, 4, 5]]

remove(l)

Which will give you:

[[3], [2], [4]]

To find the min and max in a single pass you can use a helper function:

def min_max(sub):
    # all numbers are > float("-inf") and < float("inf")
    mx, mn = float("-inf"), float("inf")
    for ele in sub:
        if ele < mn:
            mn = ele
        if ele > mx:
            mx = ele
    return {mn, mx}

def remove(l):
    for sub in l:
        # find min and max
        mn_mx = min_max(sub)
        # update sublist so all occurrences of either are removed
        sub[:] = (ele for ele in sub if ele not in mn_mx)

Even if your own logic worked and you wanted to remove all the elements equal to the max, it would not work using remove as it will only remove the first occurrence each time.

In [8]: l = [1,2,3,4,4]

In [9]: l.remove(4)

In [10]: l
Out[10]: [1, 2, 3, 4]

Based on one of your comments you seem to have strings in your sublists which will error when compared to an int, if the string is always the first element you can slice it off:

   from itertools import islice

   def remove(l):
        for sub in l:
            sub = sub[1:]
            mn_mx = min_max(sub)
            sub[:] = (ele for ele in sub if ele not in mn_mx)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
0

try this approach:

foreach innerlist:

  1. sort the array
  2. remove the first element
  3. remove the last element
ttdijkstra
  • 618
  • 4
  • 14
0

It should work like this:

myList = [[1, 3, 4], [2, 4, 4], [3, 4, 5]]
for list in myList:
   maxV = list[0] #initialise them here
   minV = list[0] #because you look for max in list
   for value in list:
      if value> maxV:
         maxV = innerlist
      if value< minV:
         minV = innerlist
   list.remove(maxV) #remove from list
   list.remove(minV)
print(myList)

Your errors where:

  1. minV = myList[0]0] a [ to little
  2. maxV = 0 works only if the list is always positive
  3. maxV and minV should be inside the first loop
  4. innerlist.remove(maxV) should be list.remove(maxV)

I also renamed innerList to value

Jan
  • 1,504
  • 10
  • 15
-1

Unindent your removes, to take them out of the loop and:

maxV = -10000000
minV = 10000000   # !!
Jacques de Hooge
  • 6,750
  • 2
  • 28
  • 45
  • 1
    Unindenting would not work if you want to remove a value from an integer. Also setting minV to the first element works and a big - and + value offers no security. You should use `sys.maxint` instead – Jan Mar 25 '16 at 17:07