Упорядочить список кортежей на основе списка строк

#python

#python

Вопрос:

У меня есть два списка order и data . order подразумевается порядок, в котором должен быть список кортежей в data .

 # two lists
order = ['name', 'email', 'phone', 'zip']
data = [(email, <object>), ('zip', <object>), ('name', <object>), ('phone', <object>)]

# what the result should be
[('name', <object>), ('email', <object>), ('phone', <object>), ('zip', <object>)]
  

Кажется, я не могу разработать хороший алгоритм для этого. Самое близкое, что я получил, это:

 result = [x for (x, y) in sorted(zip(data, order), key=lambda pair: pair[0])]
  

Который просто упорядочивает все в алфавитном порядке.

Есть мысли о хорошем способе сделать это?

Ответ №1:

Вам просто нужно отсортировать по первому элементу ваших кортежей данных на основе его индекса в порядке:

 order = ['name', 'email', 'phone', 'zip']
data = [("email", "<object>"), ('zip', "<object>"), ('name', "<object>"), ('phone', "<object>")]

print sorted(data,key=lambda x:order.index(x[0]))
[('name', '<object>'), ('email', '<object>'), ('phone', '<object>'), ('zip', '<object>')]
  

Вы также можете сортировать на месте:

 data.sort(key=lambda x:order.index(x[0]))
print data
[('name', '<object>'), ('email', '<object>'), ('phone', '<object>'), ('zip', '<object>')]
  

Это также сработает, если у вас есть повторяющиеся элементы:

 data = [("email", "<object>"),("email", "<object>"), ('zip', "<object>"), ('name', "<object>"), ('phone', "<object>"),('name', "<object>")]
data.sort(key=lambda x:order.index(x[0]))
print data
[('name', '<object>'), ('name', '<object>'), ('email', '<object>'), ('email', '<object>'), ('phone', '<object>'), ('zip', '<object>')]
  

Комментарии:

1. многие хорошие решения, показывающие, что мне нужно больше копаться в Python и лучше понимать его, не часто нуждаются в этом. Выбрал этот, потому что я понимаю его лучше всего, и это одна строка.

2. @percent, я также добавил способ сортировки списка на месте.

Ответ №2:

Как насчет использования словаря в качестве посредника?

 index = { t[0]: t for t in data }
result = [index[k] for k in order]
  

Ответ №3:

Вы могли бы превратить order в dict

 >>> data = [('email', None), ('zip', None), ('name', None), ('phone', None)]
>>> order = {'name':0, 'email':1, 'phone':2, 'zip':3}
>>> sorted(data, key=lambda item : order[item[0]])
[('name', None), ('email', None), ('phone', None), ('zip', None)]
  

Комментарии:

1. index = {item: order.index(item) for item in order} в качестве предложения