упорядочение списка кортежей на основе элементов другого списка - PullRequest
0 голосов
/ 29 января 2019

У меня есть 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 голосов
/ 30 января 2019

Если вы хотите использовать функцию sorted() с ключом, вы можете преобразовать список list50 в словарь списков, где каждый список содержит индексы соответствующего элемента в 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)]

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

Если вы хотите сохранить порядок кортежей с одинаковыми первыми элементами, как в исходном списке, используйте deque и метод 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)]
0 голосов
/ 29 января 2019

Вы можете преобразовать list100 в dict и просто перечислить элементы в list50 с их значениями в dict:

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