Python: Как сделать заказ списка? - PullRequest
8 голосов
/ 02 сентября 2010

Obs: я знаю, что списки в python не являются фиксированными по порядку, но думаю, что этот будет.И я использую Python 2.4

У меня есть список, например (например) этот:

mylist = [ ( u'Article', {"...some_data..."}    ) ,
           ( u'Report' , {"...some_data..."}    ) ,
           ( u'Book'   , {"...another_data..."} ) ,
...#continue
]

Эта переменная mylist получена из функции, а 'order' извозвращаемый список будет отличаться.Так что иногда это будет похоже на пример.Иногда, «Отчет» будет стоять перед «Статьей» и т. Д.

У меня есть фиксированный порядок, который я хочу в этом списке (и не в алфавитном порядке).мой фиксированный порядок: «Отчет», «Статья», «Книга», ...

Итак, я хочу, чтобы: каков бы ни был создан экземпляр «Мой список», я хочу изменить его порядок создания »Отчет«останься впереди», «статья» на втором и т.д.

Ответ :

Я закончил с этим:

mylist стал списком диктов, например:

mylist = [{'id':'Article', "...some_data..."} ,
        ...etc
]

у каждого диктанта есть «id», который должен быть отсортирован.

Сохранение правильного порядка в списке. Назначение правильного порядка в списке:

correct_order = ['Report', 'Article', 'Book', ...]

и выполнение:

results = sorted([item for item in results], cmp=lambda x,y:cmp(correct_order.index(x['id']), correct_order.index(y['id'])))

Ответы [ 4 ]

16 голосов
/ 02 сентября 2010

Вы можете использовать словарь, который отображает каждый первый элемент в его «вес», а затем проверять этот словарь внутри функции сортировки.

Что-то вроде:

d = { "Report": 1,
      "Article": 2,
       "Book": 3 }
result = sorted(mylist, key=lambda x:d[x[0]])
6 голосов
/ 02 сентября 2010

Вы можете использовать словарь, который позволит вам получить доступ к «Книге», «Статье» и т. Д., Не заботясь о порядке.Я бы поместил данные из этого списка в текст, который выглядит следующим образом:

mydict = { u'Article': "somedata",
           u'Report': "someotherdata", ...}

Если вы действительно хотите отсортировать свой список так, как вы описали, вы можете использовать list.sort с ключевой функциейкоторый представляет ваш конкретный порядок сортировки ( Документация ).Вам нужна ключевая функция, так как вам нужен доступ только к первому элементу, и ваш порядок сортировки также не в алфавитном порядке.

2 голосов
/ 02 сентября 2010

Таким образом создается дикт и извлекает из него элементы в порядке

mylist = [ ( u'Article', {"...some_data..."}    ) ,
           ( u'Report' , {"...some_data..."}    ) ,
           ( u'Book'   , {"...another_data..."} ) ,
]

mydict = dict(mylist)
ordering = [u'Report', u'Article', u'Book']

print [(k,mydict[k]) for k in ordering]

Этот способ использует сортировку с O (1) поисками для заказа

mylist = [ ( u'Article', {"...some_data..."}    ) ,
           ( u'Report' , {"...some_data..."}    ) ,
           ( u'Book'   , {"...another_data..."} ) ,
]

mydict = dict(mylist)
ordering = dict((k,v) for v,k in enumerate([u'Report', u'Article', u'Book']))

print sorted(mydict.items(), key=lambda (k,v): ordering[k])
1 голос
/ 28 февраля 2018

В более общем случае могут быть элементы mylist, которые не находятся в указанном фиксированном порядке. Это упорядочит в соответствии с правилом, но оставит в покое относительный порядок всего, что находится вне правила:

def orderListByRule(alist,orderRule,listKeys=None,dropIfKey=None):
    ###
    #######################################################################################
    """ Reorder alist according to the order specified in orderRule. The orderRule lists the order to be imposed on a set of keys. The keys are alist, if listkeys==None, or listkeys otherwise.  That is, the length of listkeys must be the same as of alist. That is, listkeys are the tags on alist which determine the ordering.  orderRule is a list of those same keys and maybe more which specifies the desired ordering.
    There is an optional dropIfKey which lists keys of items that should be dropped outright.
    """
    maxOR = len(orderRule)
    orDict = dict(zip(orderRule, range(maxOR)))
    alDict = dict(zip(range(maxOR, maxOR+len(alist)),
                      zip(alist if listKeys is None else listKeys, alist)))
    outpairs = sorted(  [[orDict.get(b[0],a),(b)] for a,b in alDict.items()]  )
    if dropIfKey is None: dropIfKey=[]
    outL = [b[1] for a,b in outpairs if b[0] not in dropIfKey]
    return outL

def test_orderListByRule():
    L1 = [1,2,3,3,5]
    L2 = [3,4,5,10]
    assert orderListByRule(L1, L2) == [3, 3, 5, 1, 2]
    assert orderListByRule(L1, L2, dropIfKey=[2,3]) == [5, 1,]
    Lv = [c for c in 'abcce']
    assert orderListByRule(Lv, L2, listKeys=L1) == ['c', 'c', 'e', 'a', 'b']
    assert orderListByRule(Lv, L2, listKeys=L1, dropIfKey=[2,3]) == ['e','a']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...