-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)
。你知道这个解决方案的复杂性吗?