3

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

这就是我现在的做法,但有人可以提出更好/更有效的方法吗?

    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))
4

5 回答 5

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其相对于其他元素的相对顺序。例如ais 0, bis1
  • 然后我们排序originalList。如果字典中存在其元素之一order,则使用其相对位置进行排序。如果它不存在,则返回一个正无穷大值——这将保证不在其中的元素listTemplate最终会出现,它们之间没有进一步的排序。

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

于 2013-08-15T18:13:53.307 回答
1

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

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

用于enumerate创建以项目为键的字典(考虑到项目是可散列的)和索引作为值。

>>> 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']
于 2013-08-15T18:11:18.113 回答
0

对于最后一步,您可以使用:

listFinal += originalList

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

于 2013-08-15T18:09:46.453 回答
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)
于 2013-08-15T18:11:35.093 回答
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']
于 2013-08-15T18:31:06.047 回答