根据其他列表中的元素对元组列表进行排序

时间:2019-01-29 14:33:45

标签: python list tuples

我有2个列表,如下所示。我希望根据list100

中元素的顺序对列表list50进行排序
list50 = ['cat', ,'bat', 'cat', 'cat', 'bat', 'No Data', 'bat', 'No Data']
list100 = [('cat', 100),
  ('cat', 100),
  ('cat', 100),
  ('bat', 67),
  ('bat', 67),
  ('bat', 67),
  ('No Data', 40),
  ('No Data', 40)]

我希望将列表list100转到

[('cat', 100),
  ('bat', 67),
  ('cat', 100),
  ('cat', 100),
  ('bat', 67),
  ('No Data', 40),
  ('bat', 67),
  ('No Data', 40)
  ]

有什么方法使之成为可能?

2 个答案:

答案 0 :(得分:4)

您可以将list100转换为字典,并简单地将list50中的项目及其在字典中的值列出:

d = dict(list100)
[(k, d[k]) for k in list50]

这将返回:

[('cat', 100), ('bat', 67), ('cat', 100), ('cat', 100), ('bat', 67), ('No Data', 40), ('bat', 67), ('No Data', 40)]

答案 1 :(得分:0)

如果要通过键使用函数sorted(),可以将列表list50转换为列表字典,其中每个列表都包含list50中对应元素的索引。每次调用key函数时,都会从列表中删除最后一个元素。

list50 = ['cat', 'bat', 'cat', 'cat', 'bat', 'No Data', 'bat', 'No Data']
list100 = [('cat', 100), ('cat', 100), ('cat', 100), ('bat', 67), ('bat', 67), ('bat', 67), ('No Data', 40), ('No Data', 40)]

lookup = {}
for num, el in enumerate(list50):
    lookup.setdefault(el, []).append(num)       
# print(lookup)
# {'cat': [0, 2, 3], 'bat': [1, 4, 6], 'No Data': [5, 7]}     

list100_ = sorted(list100, key=lambda x: lookup[x[0]].pop())   
# [('cat', 100), ('bat', 67), ('cat', 100), ('cat', 100), ('bat', 67), ('No Data', 40), ('bat', 67), ('No Data', 40)]

如果要保持元组的顺序与原始列表中的第一个元素相同,请使用双端队列和方法popleft()从列表中弹出第一个元素:

list50 = ['cat', 'bat', 'cat', 'cat', 'bat', 'No Data', 'bat', 'No Data']
list100 = [('cat', 1), ('cat', 2), ('cat', 3), ('bat', 1), ('bat', 2), ('bat', 3), ('No Data', 1), ('No Data', 2)]

from collections import deque

lookup = {}
for num, el in enumerate(list50):
    lookup.setdefault(el, deque()).append(num)
# print(lookup)
# {'cat': deque([0, 2, 3]), 'bat': deque([1, 4, 6]), 'No Data': deque([5, 7])}     

list100_ = sorted(list100, key=lambda x: lookup[x[0]].popleft())
#[('cat', 1), ('bat', 1), ('cat', 2), ('cat', 3), ('bat', 2), ('No Data', 1), ('bat', 3), ('No Data', 2)]