开发者

Fill list with objects and sort (Newbie)

I'm new to Python, so please forgive me when using wrong terms :)

I'd like to have a list of several "objects", each of them having the same numeric attributes (A, B, C). This list should then be sorted by the value of attribute A.

In Java I'd de开发者_如何转开发fine a Class with my attributes as members, implement Sortable to compare A, put them all in some sort of List and let Collections.sort sort my list.

The result should "look" like that:

A   B   C
1   2   3
1   2   4
2   5   1
3   1   1

What is the best way to do something like that in Python?


class myclass(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def __repr__(self):
        return "(a=%s, b=%s, c=%s)" % (self.a, self.b, self.c)

>>> obj1 = myclass(1, 2, 3)
>>> obj2 = myclass(1, 2, 4)
>>> obj3 = myclass(2, 5, 1)
>>> obj4 = myclass(3, 1, 1)

>>> print sorted([obj1, obj2, obj3, obj4], key=lambda o: o.a)
[(a=1, b=2, c=3), (a=1, b=2, c=4), (a=2, b=5, c=1), (a=3, b=1, c=1)]


Sorry, If I took your question wrong way. I don't get it very well.

So, I will assume like you want to sort by column

Lets say x is 2 dimensional array

>>> x=[[1, 2, 3], [1, 2, 4], [2, 5, 1], [3, 1, 1]]
>>> x
[[1, 2, 3], [1, 2, 4], [2, 5, 1], [3, 1, 1]]

here is one way to do sorting by each column, using itemgetter

from operator import itemgetter

>>> sorted(x,key=itemgetter(0))
[[1, 2, 4], [1, 2, 3], [2, 5, 1], [3, 1, 1]]
>>> sorted(x,key=itemgetter(1))
[[3, 1, 1], [1, 2, 4], [1, 2, 3], [2, 5, 1]]
>>> sorted(x,key=itemgetter(2))
[[3, 1, 1], [2, 5, 1], [1, 2, 3], [1, 2, 4]]

If you want in-place sorting, please do like x.sort(key=itemgetter(0))


Consider using a namedtuple to create your objects. (Have a look at is-there-a-tuple-data-structure-in-python.)

collections.namedtuple(typename, field_names[, verbose])

Returns a new tuple subclass named typename. The new subclass is used to create tuple-like objects that have fields accessible by attribute lookup as well as being indexable and iterable. Instances of the subclass also have a helpful docstring (with typename and field_names) and a helpful repr() method which lists the tuple contents in a name=value format.

A simple interactive session with A B C field names. Sorting is straightforward with key=lambda o:o.A:

>>> import collections
>>> mob=collections.namedtuple('myobj',('A','B','C'))
>>> mlist = [mob(3,1,1), mob(1,2,3), mob(1,2,4), mob(2,5,1)]
>>> mlist
[myobj(A=3, B=1, C=1), myobj(A=1, B=2, C=3), myobj(A=1, B=2, C=4), myobj(A=2, B=5, C=1)]
>>> for x in sorted(mlist,key=lambda o:o.A):
...     print x
...     
myobj(A=1, B=2, C=3)
myobj(A=1, B=2, C=4)
myobj(A=2, B=5, C=1)
myobj(A=3, B=1, C=1)
>>> 


You can give a comparison function as first argument of the sort of a list See the code below:

class Foo:
    def __init__(self, a, b=0, c=0):
        self.a = a
        self.b = b
        self.c = c

    def __repr__(self):
        return "%d %d  %d" % (self.a, self.b, self.c)


foos = [Foo(2, 5, 1), Foo(1, 2, 4), Foo(3, 1, 1), Foo(1, 2, 3)]

def cmp_a(f1, f2): 
    if f1.a == f2.a:
        return 0
    elif f1.a < f2.a:
        return -1
    else:
        return 1

foos.sort(cmp_a)

for f in foos:
    print f


List = [(3,1,1),(1,2,4),(2,5,1),(1,2,3)]
sorted(List)

Update: The heart of the answer is actually the sorted built-in. I just put it on two lines to allow for incremental inspection that (a) the data structure chosen is a list of tuples, and (b) the sorting is done by sorted. As a commenter pointed out sorted() will in one go sort by A, then B, then C (whether this is required or not). Other answers make a good point about adding a key-picking function to the call to sorted(), to nail down which element will be used in the comparison. Again, whether this is advantageous or not is for the OP to judge. I wanted to offer a minimal solution.

Update1: I shuffled the elements of the list around, so it appeals more to sorting :).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜