Переключение двух списков в список

Учитывая следующий список:

my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 

Я хочу, чтобы как можно быстрее и эффективнее поменять my_list[2:4] с под-списком my_list[7:10] , чтобы получить новый список:

 new_list=[0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12] 

Вот моя попытка:

 def swap(s1, s2, l): seg1=l[:s1.start]+l[s2] seg2=l[s1.stop : s2.start] seg3=l[s1]+l[s2.stop:] return seg1+seg2+seg3 print swap(slice(2,4), slice(7,10), [0,1,2,3,4,5,6,7,8,9,10,11,12]) 

Это печатает желаемый результат, хотя этот способ делать это выглядит ужасно для меня.

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

Я не возражаю (на самом деле, я бы предпочел) изменить исходный список, а не создавать новый экземпляр каждого вызова функции.

6 Solutions collect form web for “Переключение двух списков в список”

Могут быть назначены срезы.

Две переменные могут быть заменены на a, b = b, a .

Объедините два выше ::

 >>> my_list[7:10], my_list[2:4] = my_list[2:4], my_list[7:10] >>> my_list [0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12] 

Остерегайтесь того, что – если срезы имеют разные размеры – порядок важен : если вы поменяетесь в обратном порядке, вы получите другой результат, потому что он сначала изменит начальные элементы (нижние индексы), а затем более высокие индексы ( но они будут сдвинуты в другую позицию по первому назначению).

Кроме того, срезы не должны перекрываться.

Здесь вы можете использовать обычную технику свопинга ( x,y = y,x ), но только если вы выполняете своп в правильном порядке: x должен быть вторым (самый правый) срез, а y – первым (крайний левый) срез.

 >>> my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] >>> my_list[7:10], my_list[2:4] = my_list[2:4], my_list[7:10] >>> my_list [0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12] 

Это работает, потому что my_list[7:10] будет присваиваться my_list[7:10] , и только затем в my_list[2:4] .

Если вы выполните это в обратном порядке, my_list[2:4] место расположения элементов справа из-за подписок, имеющих разную длину, что даст неверные результаты.

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

Не совсем очевидно (или эффективно), но он работает. Мне было любопытно узнать, можно ли использовать объект среза.

 import itertools def replace(s1, s2, l): lslice = [slice(0,s1.start), s2, slice(s1.stop, s2.start), s1, slice(s2.stop,len(l))] return list(itertools.chain.from_iterable([l[x] for x in lslice])) 

Я думаю, что лучше всего использовать конкатенацию и нарезку. Если вы передадите список, а затем два списка с парами индексов, вы можете просто нарезать список и перегруппировать два подсписок. Обратите внимание, что indexA и indexB работают в некотором роде как регулярная нарезка, стартовый номер включен, но в конце нет.

 def replace(source, indexA, indexB): newList = source[:indexA[0]] + source[indexB[0]:indexB[1]] newList += source[indexA[1]:indexB[0]] + source[indexA[0]:indexA[1]] newList += source[indexB[1]:] return newList myList = replace(myList, [2,4], [7,10]) 

Это другой способ сделать это:

 import itertools my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] my_list2 = [] my_list2.extend((my_list[0:2],my_list[7:10],my_list[4:7],my_list[2:4],my_list[10:])) new_list = list(itertools.chain.from_iterable(my_list2) 

new_list печати new_list :

 [0, 1, 7, 8, 9, 4, 5, 6, 2, 3, 10, 11, 12] 

Я считаю, что лучше использовать индекс списка в качестве параметров.

Если вы хотите переопределить свою замену fuction следующим образом:

 my_list=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] def slice_replace(src_list, l_start, l_end, r_start, r_end): if l_end <= r_start: return src_list[:l_start] + src_list[r_start:r_end] + src_list[l_end:r_start] + src_list[l_start:l_end] + src_list[r_end:] else: return slice_replace(src_list, r_start, r_end, l_start, l_end) print my_list new_list = slice_replace(my_list, 2, 4, 7, 10) print new_list new_list = slice_replace(my_list, 7, 10, 2, 4) print new_list 

Я исправил это.

  • Самый быстрый способ перестановки подписок в python
  • Вычислить разницу между смежными элементами в списке python
  • Python: Есть ли способ разделить строку чисел на каждый третий номер?
  • Python: удаление пробелов из объектов списка
  • Индексы списка Python должны быть целыми, а не кортежем "
  • Python - определение максимального значения во втором столбце вложенного списка
  • Добавление элемента в списки в понимании списка
  • Почему в python не работает var = .extend (range (1,10))?
  • Как я перечисляю () над списком кортежей в Python?
  • Python перебирает два списка одновременно
  • python: самый элегантный способ пересечения списка с элементом
  • Python - лучший язык программирования в мире.