Hi,

i'm new to python and I'm having a problem that I'm not able to solve.

I have the following 2D array:

``````valuearray = [['A', '21', '45'], ['A', '12', '23'],
['A', '54', '21'], ['A', '15', '54'],
['B', '23', '53'], ['B', '34', '53'],
['B', '32', '54'], ['B', '24', '13'],
['C', '31', '43'], ['C', '42', '54'],
['C', '35', '54'], ['C', '12', '11']]

A  21 45
A  12 23
A  54 21
A  15 54
B  23 53
B  34 53
B  32 54
B  24 13
C  31 43
C  42 54
C  35 54
C  12 11
``````

I need to generate from this array another array that have the unique values of valuearray[0] , the maximum of valuearray[1] for each valuearray[0] and the minimum valuearray[2] for each valuearray[0]

The result would be:

``````resarray[]

A  54 21
B  34 13
C  42 11
``````

what i tried

``````    uniquenames = []
un = []
for i in range(len(valuearray)):
un.append(valuearray[i][0])
uniquenames=uniq(un)

test = []
for ci in range(len(valuearray)):
for gn in range(len(uniquenames)):
if(valuearray[ci][0] == uniquenames[gn]):
# i don't know what to do here
i tried append(valuearray[ci][0] , max(valuearray[ci][1]),min( valuearray[ci][2]))
``````

NOTE: the array might have more than 3 columns and a big number of rows(e.g E, F, G ,...) ... so i need a dynamic result for my problem.

thank you

## All 5 Replies

Here is one way to do it

``````from operator import itemgetter
import itertools as itt

valuearray = [['A', '21', '45'], ['A', '12', '23'],
['A', '54', '21'], ['A', '15', '54'],
['B', '23', '53'], ['B', '34', '53'],
['B', '32', '54'], ['B', '24', '13'],
['C', '31', '43'], ['C', '42', '54'],
['C', '35', '54'], ['C', '12', '11']]

result = list()
for key, group in itt.groupby(valuearray, itemgetter(0)):
# replace valuearray with sorted(valuearray, key=itemgetter(0))
# if valuearray is not initially sorted.
u, v = itt.tee(group)
u, v = max(u, key=itemgetter(1))[1], min(v, key = itemgetter(2))[2]
result.append((key, u, v))

print result
""" my output -->
[('A', '54', '21'), ('B', '34', '13'), ('C', '42', '11')]
"""
``````

I don't understand which result you want when there are more than 3 columns. What should the extra columns contain in the result ?

An alternative is

``````result = list()
for key, group in itt.groupby(valuearray, itemgetter(0)):
u, v = zip(*(t[1:3] for t in group))
result.append((key, max(u), min(v)))
``````

this solve my problem, but when i have more than 1 columns (i mean i only need these values but from a list which have more than 3 columns)

A better solution would probably to write a generating function like this one

``````def extremes(records):
for key, group in itt.groupby(records, itemgetter(0)):
M, m = next(group)[1:3]
for record in group:
M, m = max(M, record[1]), min(m, record[2])
yield (key, M, m)

print list(extremes(valuearray))
``````

It's advantages over the previous versions is that it does not store more than one record at a time. The argument can be an iterable (not necessarily a list). For example one could read the records in a file and write the result in another file, and very little memory would be used. It also works if there are more than 3 columns. Notice that the initial data need to be sorted on the key.

Take care that you have strings, not integer values, so '9' would be maximum at column 1 and '10000' would be minimum at column 2.

commented: important comment +2

Take care that you have strings, not integer values, so '9' would be maximum at column 1 and '10000' would be minimum at column 2.

Oh yes it is true. Here is the corrected version

``````def extremes(records):
for key, group in itt.groupby(records, itemgetter(0)):
M, m = (int(x) for x in next(group)[1:3])
for record in group:
M, m = max(M, int(record[1])), min(m, int(record[2]))
yield (key, str(M), str(m))

print list(extremes(valuearray))
``````
commented: thank you +2
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.