pumpkin
pumpkin

Reputation: 57

How to make a list of the maximums in a list of lists (python)

Out of all the little lists, I have to make one list with the maximum even number out of each of the lists. If the list has odd numbers then the maximum is 0. So far my code is:

a=[]
b=[]
c=''
d=''
e=''
for i in range (len(res)):
    for j in range (len(res)):
        d=res[i][j]
        if (d%2 == 0):
            d=d
            a.append(d)
        else:
            d= 0
            a.append(d)
    c = max(a)
    b.append(c)
print b

The list is [[1,2,3],[6,5,4],[5,7,9]] and I need to get [2,6,0] but instead I keep getting [2,6,6]

Upvotes: 1

Views: 190

Answers (4)

twasbrillig
twasbrillig

Reputation: 18821

max takes an optional key function which can be used to keep odd numbers out of the running. See https://docs.python.org/library/functions.html#max

def fn(x):
    return x if x % 2 == 0 else float("-inf")

a = [[1,2,3],[6,5,4],[5,7,9]]
b = [ max(L, key=fn) for L in a ]
print([i if i % 2 == 0 else 0 for i in b])

gives [2, 6, 0]

Works with negative numbers too. (If you don't need to support negative numbers, you can replace float("-inf") with -1.)

Upvotes: 1

Shawn Zhang
Shawn Zhang

Reputation: 1852

a = [[1,2,3],[6,5,4],[5,7,9]]
[ max( filter(lambda y: y % 2 ==0,(i+[0]))) for i in a]
>>>[2, 6, 0]

I think the code is quite self explanatory:

  • max(seq) return a biggest number in the sequence
  • filter(fn, seq) , will apply each element in seq with function fn, and keep element with fn(element) is logical true.
  • list + [0] will be return a new list with one more element "0",just in case all elements in the list is odd number .

Update: in case of neg even, (credit should be give to @twasbrillig )

[ 0 if all(map(lambda z: z%2,i)) == True else max( filter(lambda y: y % 2 ==0,i)) for i in a]

Upvotes: 1

polarise
polarise

Reputation: 2413

Several points.

One, replace range with xrange. It doesn't create the full list.

Second, it appears that you are iterating over a 'matrix'. I had assumed that all the little lists were of indeterminate size. Nevertheless you are performing n*n evaluations. You could instead perform n+n by first finding the max then checking for evenness or oddness.

maxes = [ max( row ) for row in res ]
res_final = [ m if m % 2 == 0 else 0 for m in maxes ]

You'll have to double check the last line. But that should do.

Upvotes: 0

dreyescat
dreyescat

Reputation: 13798

As max function accepts an iterable, you can just use:

>>> a = [[1,2,3],[6,5,4],[5,7,9]]
>>> [max([m for m in i if m % 2 == 0] or [0]) for i in a]
[2, 6, 0]

Where [m for m in i if m % 2 == 0] gets the list of even numbers, and max([m for m in i if m % 2 == 0] or [0]) gets the max even number (negative included) or 0 if no even number exists.

>>> a = [[1,2,3],[6,5,4],[5,7,9,-2]]
>>> [max([m for m in i if m % 2 == 0] or [0]) for i in a]
[2, 6, -2]

Upvotes: 1

Related Questions