-Python-基于格式的订购列表

时间:2013-08-15 18:04:32

标签: python list

我是一般的编程新手,所以希望在这里真正扩展我的技能。我正在尝试编写一个脚本,它将从对象中获取字符串列表,然后根据我的设计模板对它们进行排序。不在模板中的任何项目都将添加到最后。

以下是我现在正在做的事情,但是有人会建议更好/更有效的方法吗?

    originalList = ['b', 'a', 'c', 'z', 'd']
    listTemplate = ['a', 'b', 'c', 'd']
    listFinal = []

    for thing in listTemplate:
        if thing in originalList:
            listFinal.append(thing)
            originalList.pop(originalList.index(thing))

    for thing in originalList:
            listFinal.append(thing)
            originalList.pop(originalList.index(thing))

5 个答案:

答案 0 :(得分:2)

试试这个:

originalList = ['b', 'a', 'c', 'z', 'd']
listTemplate = ['a', 'b', 'c', 'd']

order = { element:index for index, element in enumerate(listTemplate) }
sorted(originalList, key=lambda element: order.get(element, float('+inf')))

=> ['a', 'b', 'c', 'd', 'z']

这是它的工作原理:

  • 首先,我们构建一个字典,为listTemplate中的每个元素指示其相对于其他元素的相对顺序。例如,a0b1,依此类推
  • 然后我们对originalList进行排序。如果order字典中存在其中一个元素,则使用其相对位置进行排序。如果它不存在,则返回正无限值 - 这将保证不在listTemplate中的元素最终会结束,而不会在它们之间进一步排序。

问题中的解决方案虽然正确,但并不是非常pythonic。特别是,每当您必须构建新列表时,请尝试使用列表推导而不是显式循环/追加。并且“破坏”输入列表并不是一个好习惯(在这种情况下使用pop())。

答案 1 :(得分:1)

您可以使用listTemplate列表创建一个字典,这样可以将昂贵的(O(N)list.index操作简化为O(1)次查找。

>>> lis1 = ['b', 'a', 'c', 'z', 'd']
>>> lis2 = ['a', 'b', 'c', 'd']

使用enumerate创建一个带有项目作为键的dict(考虑到项目是可以清除的)并将索引作为值。

>>> dic = { x:i for i,x in enumerate(lis2) }

现在dic看起来像:

{'a': 0, 'c': 2, 'b': 1, 'd': 3}

现在对于lis1中的每个项目,我们需要在dic中检查它的索引,如果找不到密钥,我们会返回float('inf')

用作key的函数:

def get_index(key):
   return dic.get(key, float('inf'))

现在对列表进行排序:

>>> lis1.sort(key=get_index)
>>> lis1
['a', 'b', 'c', 'd', 'z']

答案 2 :(得分:0)

最后一步,你可以使用:

listFinal += originalList

它会将这些项添加到最后。

答案 3 :(得分:0)

这是一种具有更好计算复杂性的方法:

# add all elements of originalList not found in listTemplate to the back of listTemplate
s = set(listTemplate)
listTemplate.extend(el for el in originalList if el not in s)

# now sort
rank = {el:index for index,el in enumerate(listTemplate)}
listFinal = sorted(originalList, key=rank.get)

答案 4 :(得分:0)

根本不需要创建新词典:

>>> len_lis1=len(lis1)

>>> lis1.sort(key = lambda x: lis2.index(x) if x in lis2 else len_lis1)

>>> lis1
    ['a', 'b', 'c', 'd', 'z']