Изменить порядок списка списков в соответствии с другим списком

У меня есть куча CSV-файлов, где первая строка – это имя столбца, и теперь я хочу изменить порядок в соответствии с другим списком.
Пример:

[ ['date','index','name','position'], ['2003-02-04','23445','Steiner, James','98886'], ['2003-02-04','23446','Holm, Derek','2233'], ... ] 

Вышеуказанный порядок немного отличается между файлами, но одинаковые имена столбцов всегда доступны.

Поэтому я хочу, чтобы столбцы были перегруппированы так:

 ['index','date','name','position'] 

Я могу решить эту проблему, сравнив первую строку, указав индекс для каждого столбца, а затем перегруппируйте каждую строку в новый список списков с помощью цикла for.
И пока он работает, он чувствует себя настолько уродливым, даже моя слепая старая тетя будет кричать на меня, если увидит это.

Кто-то из IRC сказал мне посмотреть на map() и operator но я просто недостаточно опытен, чтобы разгадать их вместе. : /

Благодарю.

Обычный Python

Вы можете использовать zip для переноса данных:

 data = [ ['date','index','name','position'], ['2003-02-04','23445','Steiner, James','98886'], ['2003-02-04','23446','Holm, Derek','2233'] ] columns = list(zip(*data)) print(columns) # [('date', '2003-02-04', '2003-02-04'), ('index', '23445', '23446'), ('name', 'Steiner, James', 'Holm, Derek'), ('position', '98886', '2233')] 

Теперь становится намного проще изменять порядок столбцов.

Чтобы вычислить необходимую перестановку, вы можете использовать:

 old = data[0] new = ['index','date','name','position'] mapping = {i:new.index(v) for i,v in enumerate(old)} # {0: 1, 1: 0, 2: 2, 3: 3} 

Вы можете применить перестановку к столбцам:

 columns = [columns[mapping[i]] for i in range(len(columns))] # [('index', '23445', '23446'), ('date', '2003-02-04', '2003-02-04'), ('name', 'Steiner, James', 'Holm, Derek'), ('position', '98886', '2233')] 

и перенести их обратно:

 list(zip(*columns)) # [('index', 'date', 'name', 'position'), ('23445', '2003-02-04', 'Steiner, James', '98886'), ('23446', '2003-02-04', 'Holm, Derek', '2233')] 

С Пандами

Для таких задач вы должны использовать панды . Он может анализировать CSV, изменять порядок столбцов, сортировать их и хранить индекс.

Если вы уже импортировали data , вы можете использовать эти методы для импорта столбцов, использовать первую строку в качестве заголовка и установить index столбец в качестве индекса.

 import pandas as pd df = pd.DataFrame(data[1:], columns=data[0]).set_index('index') 

df тогда становится:

  date name position index 23445 2003-02-04 Steiner, James 98886 23446 2003-02-04 Holm, Derek 2233 

Вы можете избежать этих шагов, импортировав CSV правильно с помощью pandas.read_csv . Для получения правильного порядка вам понадобится usecols=['index','date','name','position'] .

Простой и глупый:

 LIST = [ ['date', 'index', 'name', 'position'], ['2003-02-04', '23445', 'Steiner, James', '98886'], ['2003-02-04', '23446', 'Holm, Derek', '2233'], ] NEW_HEADER = ['index', 'date', 'name', 'position'] def swap(lists, new_header): mapping = {} for lst in lists: if not mapping: mapping = { old_pos: new_pos for new_pos, new_field in enumerate(new_header) for old_pos, old_field in enumerate(lst) if new_field == old_field} yield [item for _, item in sorted( [(mapping[index], item) for index, item in enumerate(lst)])] if __name__ == '__main__': print(LIST) print(list(swap(LIST, NEW_HEADER))) 

Чтобы переупорядочить данные, вы можете использовать словарь:

 import csv s = [ ['date','index','name','position'], ['2003-02-04','23445','Steiner, James','98886'], ['2003-02-04','23446','Holm, Derek','2233'], ] new_data = [{a:b for a, b in zip(s[0], i)} for i in s[1:]] final_data = [[b[c] for c in ['index','date','name','position']] for b in new_data] write = csv.writer(open('filename.csv')) write.writerows(final_data)