1

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

EDIT: sorry for not presenting 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]))

but append only take one parametre, so I don't know how to continue.

And uniq is a function that gives me the unique values from a list.

5
  • 4
    Fascinating. What have you tried? Commented Apr 29, 2012 at 11:19
  • Downvoting. Make an effort besides just transcribing your homework. Commented Apr 29, 2012 at 11:27
  • Are all A's, B's, and C's grouped together and arranged in order? Commented Apr 29, 2012 at 12:12
  • Also, try to represent your arrays in the format they are in Python. Commented Apr 29, 2012 at 12:12
  • yes, i used the sorted function to arrange them .. Commented Apr 29, 2012 at 12:13

1 Answer 1

3

We can do this pretty easily with itertools.groupby and zip():

data = [
    ['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']
]

from itertools import groupby
from operator import itemgetter

for name, values in groupby(data, itemgetter(0)):
    _, first, second = zip(*values)
    print(name, max(first), min(second))

What we are doing here is using groupby() to group the list items by the first item. This gives us three lists - a list for the records beginning with A, then a list for B, then C. It's also worth noting that groupby() doesn't require your list to be sorted.

We then extract the values from these lists by using zip() to unzip the values from a list of triplets into three lists of single values. We throw away the first column as it's just A, B or C as is relevant, and then take the maximum and minimum of the other columns to get the values you wanted.

Which gives us:

A 54 21
B 34 13
C 42 11

Edit:

If you have your values as text, then you can use a list comprehension and str.split() to make a list out of it:

data = """\
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\
"""

data = [value.split() for value in data.split("\n")]

Another Edit:

As per the chat, you can discard extra columns like so:

Python 3.x:

for name, values in groupby(data, itemgetter(0)):
    _, first, second, *_ = zip(*values)
    print(name, max(first), min(second))

Python 2.x:

for name, values in groupby(data, itemgetter(0)):
    first, second = zip(*values)[1:3]
    print name, max(first), min(second)

And to make the output a list, rather than printing the values:

def max_min_by_group(group):
    for name, values in group:
        _, first, second, *_ = zip(*values)
        yield [name, max(first), min(second)]

new = [item for item in max_min_by_group(groupby(data, itemgetter(0)))]

We simply use a list comprehension and a generator (we could do this in one big line but it would be unwieldy and unreadable). This gives us:

[['A', '54', '21'], ['B', '34', '13'], ['C', '42', '11']]
Sign up to request clarification or add additional context in comments.

11 Comments

@ifreak As you said 'I have a 2D array', I presumed you had a list of lists.
yes, but this will woek in case i had to add other columns to the array ?? or other rows ??
@ifreak: If you read it, you can clearly see this will work if you add more rows, however, it would not work with more columns - you did not mention it needing to work with more columns, and did not say how you wanted more columns to act if they were added.
basically i've got the list from a text file, but i might need to add columns to the file and then do this method, in this case how should i act(update the code) to make it more dynamic ???
@ifreak You are not being very clear. What do you want new columns to do? What do you mean by 'more dynamic'?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.