2015-09-29 3 views
1

У меня есть список в Python, и я ищу инвертировать каждую пару элементов в списке. Вот список:Python инвертирует каждые два элемента списка

list_ty = ['many_ord','many','12_FH_Temp_ord','12_FH_Temp','Celsius_ord','Celsius','Pressure_Pas_ord','Pressure_Pas','Kelvin_ord','Kelvin'] 

Вот что я хотел бы получить:

list_out = ['many','many_ord','12_FH_Temp','12_FH_Temp_ord','Celsius','Celsius_ord','Pressure_Pas','Pressure_Pas_ord','Kelvin','Kelvin_ord'] 

Дополнительная информация:

Там всегда будет четное число элементов в списке.

Элемент, заканчивающийся _ord, всегда будет находиться перед товаром без _ord.

Вопрос:

Есть ли способ, чтобы изменить порядок каждого элемента, заканчивающийся _ord и следующий (попутный) пункт без _ord?

+0

Ключ итерация по списку парами элементов, для которых есть много ответов на http://stackoverflow.com/questions/5389507/iterating-over- every-two-elements-in-a-list –

ответ

0

Как об этом способе:

>>> sum(zip(list_ty[1::2], list_ty[::2]),()) 
('many', 'many_ord', '12_FH_Temp', '12_FH_Temp_ord', 'Celsius', 'Celsius_ord',  'Pressure_Pas', 'Pressure_Pas_ord', 'Kelvin', 'Kelvin_ord') 
>>> 
+1

Большое спасибо за это! Мне нравится это, и он работает по мере необходимости. –

+0

Просто предупреждение, если производительность всегда вызывает беспокойство: это построит и уничтожит огромное количество «кортежей»; два элемента, сделанные 'zip', можно сделать близкими к свободным, используя версию« zip »Py3 от' future_builtins', но она создаст серию len 2, len 4, len 6 и т. д. 'tuple' s, перестраивая один раз для каждой пары элементов в 'list_ty'. Если «список» известен как маленький, то неважно, но если он может быть длинным, то в основном все остальные решения превосходят, поскольку они избегают создания тонны временных рядов во время работы. – ShadowRanger

2

Ленивый путь:

>>> [x + y for x in list_ty if not x.endswith('_ord') for y in ('', '_ord')] 
['many', 'many_ord', '12_FH_Temp', '12_FH_Temp_ord', 'Celsius', 'Celsius_ord', 'Pressure_Pas', 'Pressure_Pas_ord', 'Kelvin', 'Kelvin_ord'] 

Игнорируйте любые записи, которые заканчиваются на «_ord», и только чередующимся добавить его к другим элементам.

3

Возможно, немного глупо, как однострочник, но здесь вы идете:

from itertools import chain 

list_out = list(chain.from_iterable(zip(list_ty[1::2], list_ty[::2]))) 

Для объяснения: Мы используем нарезку на шаге 2 со смещением 1, чтобы получить значение в нечетных индексах и другой срез на шаг 2 со смещением 0 для получения четных индексов. We zip их вместе, делая [even, odd, even, odd,...] в ((odd, even), (odd, even), ...), затем используя chain.from_iterable, чтобы сгладить эти tuple s и list, чтобы реализовать генератор chain.

5

Используйте петлю for и шаг 2 элемента за раз. Вы можете использовать основной переменную питон своп затем:

a, b = b, a 

list_ty = ['many_ord','many','12_FH_Temp_ord','12_FH_Temp','Celsius_ord','Celsius','Pressure_Pas_ord','Pressure_Pas','Kelvin_ord','Kelvin'] 

for i in range(0, len(list_ty), 2): 
    list_ty[i], list_ty[i+1] = list_ty[i+1], list_ty[i] 

list_ty имеет следующее значение после этого цикла:

['many', 'many_ord', '12_FH_Temp', '12_FH_Temp_ord', 'Celsius', 'Celsius_ord', 'Pressure_Pas', 'Pressure_Pas_ord', 'Kelvin', 'Kelvin_ord'] 
+0

Мне очень нравится этот подход. Спасибо, что опубликовали его. –

2

Есть много способов сделать это, и вот один с range(len()):

list_out = [list_ty[idx+2*(not idx%2)-1] for idx in range(len(list_ty))] 

Это проходит через каждый возможный индекс в исходном списке и захватывает элемент до или после этого индекса.

0 будет захватывать товар по индексу 0 + 2*(not 0%2)-1 или 0 + 2*(not 0)-1 или 0 + 2*1-1 или 1.

1 будет улавливать товар по индексу 1 + 2*(not 1%2)-1 или 1 + 2*(not 1)-1 или 1 + 2*0-1 или 0.

2 будет захватывать товар по индексу 2 + 2*(not 2%2)-1 или 2 + 2*(not 0)-1 или 2 + 2*1-1 или 3.

3 будет захватить этот пункт на индекс 3 + 2*(not 3%2)-1 или 3 + 2*(not 1)-1 или 3 + 2*0-1 или 2.

Как вы можете видеть, вместо 0123 оно идет 1032, и этот шаблон будет продолжаться до тех пор, пока результат не будет завершен.

+1

Я не согласен с этим. С одной стороны, 'idx + 2 * (not idx% 2) -1' является абсурдно загадочным, полагаясь на забавно неинтуитивное поведение. С другой стороны, я обожаю умный код, даже если это тот ум, который автор не понимает через неделю. :-) – ShadowRanger

+0

@ShadowRanger - Ну, это код Python для алгоритма, который я хотел. Я решил не использовать тернарный оператор, но вы можете использовать его и выразить индексирование как «[idx- (1 if idx% 2 else -1)]» или '[idx-1, если idx% 2 else idx + 1] '. Если вы найдете их более ясными, я буду рад добавить их в ответ. – TigerhawkT3

+0

Нет, я не критиковал, это было сделано как комплимент больше всего на свете. – ShadowRanger

Смежные вопросы