Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
-Python-基于格式的排序列表_Python_List - Fatal编程技术网

-Python-基于格式的排序列表

-Python-基于格式的排序列表,python,list,Python,List,我对编程基本上是新手,所以希望在这里真正扩展我的技能。我试图编写一个脚本,从一个对象中获取字符串列表,然后根据我设计的模板对它们进行排序。模板中未包含的任何项目都将添加到末尾 我现在是这样做的,但是有人能建议一个更好/更有效的方法吗 originalList = ['b', 'a', 'c', 'z', 'd'] listTemplate = ['a', 'b', 'c', 'd'] listFinal = [] for thing in listTemplat

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

我现在是这样做的,但是有人能建议一个更好/更有效的方法吗

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

对于最后一步,您只需使用:

listFinal += originalList

它会将这些项目添加到末尾。

您可以使用
listTemplate
列表创建一个dict,这样昂贵的(
O(N)
列表。索引操作可以简化为
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')

用作
键的函数

def get_index(key):
   return dic.get(key, float('inf'))
现在对列表进行排序:

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

以下是一种计算复杂度更高的方法:

# 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)
试试这个:

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']
这就是它的工作原理:

  • 首先,我们为
    listmplate
    中的每个元素构建一个字典,指出其相对于其他元素的相对顺序。例如
    a
    0
    b
    1
    等等
  • 然后我们对原始列表进行排序。如果它的一个元素出现在
    order
    字典中,则使用它的相对位置进行排序。如果不存在,则返回一个正的无穷大值-这将保证不在
    listTemplate
    中的元素将在末尾结束,而它们之间没有进一步的排序

这个问题的解决方案虽然正确,但不是很符合实际。特别是,每当您必须构建一个新列表时,请尝试使用列表理解而不是显式循环/追加。“销毁”输入列表(在本例中使用
pop()
)不是一种好的做法。

根本不需要创建新词典:

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

你做得很好。也许有人知道一种更有效的方法……它可能不适用于您的用例,但正如您所知,如果
originalList
只包含唯一的元素,
set(listTemplate+originalList)
就可以了。@AshwiniChaudhary惊讶于我们得出了相同的答案!我会把我的解释留一段时间,以防有人发现解释有用,否则我会删除它。在最后一行中,它更简短地说
key=rank.get
@Joowani是的,但总体复杂性仍然是
O(NlogN)
。你知道这个解决方案的复杂性吗?