Заполнить список с объектами и сортировки (новичок) - PullRequest
0 голосов
/ 17 декабря 2009

Я новичок в Python, поэтому, пожалуйста, прости меня, если я использую неправильные термины:)

Мне бы хотелось иметь список из нескольких "объектов", каждый из которых имеет одинаковые числовые атрибуты (A, B, C). Затем этот список должен быть отсортирован по значению атрибута A.

В Java я определил бы класс с моими атрибутами в качестве членов, реализовал бы Sortable для сравнения A, поместил их все в какой-то список и позволил Collections.sort отсортировать мой список.

Результат должен «выглядеть» так:

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

Какой лучший способ сделать что-то подобное в Python?

Ответы [ 5 ]

6 голосов
/ 17 декабря 2009
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)]
4 голосов
/ 17 декабря 2009

Извините, если я неправильно понял ваш вопрос. Я не очень хорошо понимаю.

Итак, я предполагаю, что вы хотите отсортировать по столбцу

Допустим, x является двумерным массивом

>>> 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]]

вот один из способов сортировки по каждому столбцу с использованием 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]]

Если вы хотите сортировать на месте, сделайте, пожалуйста, x.sort(key=itemgetter(0))

3 голосов
/ 17 декабря 2009

Подумайте об использовании namedtuple для создания ваших объектов. (Посмотрите на is-there-a-tuple-data-structure-in-python .)

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

Возвращает новый подкласс кортежа с именем typename. Новый подкласс используется для создания объектов, похожих на кортежи, которые имеют поля, доступные для поиска по атрибутам, а также индексируемые и итерируемые. Экземпляры подкласса также имеют полезную строку документации (с typename и field_names) и полезный метод repr (), который перечисляет содержимое кортежа в формате имя = значение.

Простой интерактивный сеанс с A B C именами полей. Сортировка проста с 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)
>>> 
2 голосов
/ 17 декабря 2009

Вы можете задать функцию сравнения в качестве первого аргумента sort списка. См. Код ниже:

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
2 голосов
/ 17 декабря 2009
List = [(3,1,1),(1,2,4),(2,5,1),(1,2,3)]
sorted(List)

Обновление: сердце ответа на самом деле является sorted встроенным. Я просто поместил его в две строки, чтобы обеспечить возможность инкрементальной проверки, что (а) выбранная структура данных представляет собой список кортежей, и (б) сортировка выполняется с помощью sorted. Как отметил комментатор, sorted () за один раз отсортирует по A, затем B, затем C (требуется это или нет). Другие ответы имеют смысл добавить функцию выбора ключа в вызов sorted (), чтобы определить, какой элемент будет использоваться в сравнении. Опять же, является ли это выгодным или нет, судить должен ФП. Я хотел предложить минимальное решение.

Обновление 1: я перетасовал элементы списка, поэтому он больше подходит для сортировки:).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...