Я хотел бы переупорядочить список строк (заголовки столбцов из Pandas) в Python 2.7.13 на основе регулярного выражения. Желаемый вывод будет иметь текущий индексный пункт 0 в том же месте, за которым сразу следуют строки, найденные с использованием регулярного выражения, за которыми следуют остальные строки.
# Here the input list:
cols = ['ID', 'MP', 'FC', 'Dest_MP', 'Dest_FC', 'Origin_MP', 'Origin_FC']
# And the desired output:
output_cols = ['ID', 'FC', 'Dest_FC', 'Origin_FC', 'MP', 'Dest_MP', 'Origin_MP']
У меня есть пример рабочего кода. Это некрасиво, и поэтому я здесь.
import re
cols = ['ID', 'MP', 'FC', 'Dest_MP', 'Dest_FC', 'Origin_MP', 'Origin_FC']
pattern = re.compile(r'^FC|FC$')
matched_cols = filter(pattern.search, cols)
indices = [0] + [cols.index(match_column) for match_column in matched_cols]
output_cols, counter = [], 0
for index in indices:
output_cols.append(cols.pop(index - counter))
counter += 1
output_cols += cols
print(output_cols)
Есть ли более читаемый, более питонический способ сделать это?
Изолируйте первый элемент, никоим образом не обойти это.
Затем в остальной части списка используйте ключ сортировки, который возвращает пару:
как это:
import re
cols = ['ID', 'MP', 'FC', 'Dest_MP', 'Dest_FC', 'Origin_MP', 'Origin_FC']
new_cols = [cols[0]] + sorted(cols[1:],key=lambda x : (not bool(re.search("^FC|FC$",x)),x))
результат:
['ID', 'Dest_FC', 'FC', 'Origin_FC', 'Dest_MP', 'MP', 'Origin_MP']
если вы хотите, чтобы FC
появился первым, добавьте третье значение к возвращенному ключу. Позвольте выбрать длину строк (непонятно, что вы действительно хотите видеть как тай-брейк
key=lambda x : (not bool(re.search("^FC|FC$",x)),len(x),x)
результат:
['ID', 'FC', 'Dest_FC', 'Origin_FC', 'MP', 'Dest_MP', 'Origin_MP']
обратите внимание, что sort
стабильна, поэтому, возможно, вам не нужен тай-брейк:
new_cols = [cols[0]] + sorted(cols[1:],key=lambda x : not bool(re.search("^FC|FC$",x)))
результат:
['ID', 'FC', 'Dest_FC', 'Origin_FC', 'MP', 'Dest_MP', 'Origin_MP']