Переместить элемент в список?


Ответы:


160

Используйте insertметод списка:

l = list(...)
l.insert(index, item)

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

l[index:index] = [item]

Если вы хотите переместить элемент, который уже находится в списке, в указанную позицию, вам придется удалить его и вставить в новую позицию:

l.insert(newindex, l.pop(oldindex))

22
Просто имейте в виду, что перемещение элемента, уже находящегося в списке, с помощью метода insert / pop будет иметь разное поведение в зависимости от того, двигаетесь ли вы вперед или назад по списку. Двигаясь влево, вы вставляете перед выбранным вами объектом. Двигаясь назад, вы вставляете после выбранного вами элемента. Проверить переход в конец списка (ошибка индекса).
MKaras

Как переместить несколько элементов? Учитывая список a = [1,2,3,4,5,6,7,8,9], как преобразовать его в [1,2, [3,4,5], 6,7,8,9 ]? Можно ли это сделать за один шаг или с составлением списка?
g33kz0r

@MKaras Я тестировал это с Python 3.5, и вы МОЖЕТЕ вставить last index + 1без ошибок. В этом случае элемент просто добавляется в список.
user2061057

@ user2061057 правильный :) даже большие индексы приведут к тому, что что-то будет вставлено в конце. a.insert(99999, 1) In [14]: a Out[14]: [...., 1]
Ли Пенкман

1
Тем, кто пытается использовать индекс -1 для вставки элемента в конец, вы должны вместо этого использовать len (l).
нд

32

Немного более короткое решение, которое перемещает элемент только до конца, а не нигде:

l += [l.pop(0)]

Например:

>>> l = [1,2,3,4,5]
>>> l += [l.pop(0)]
>>> l
[2, 3, 4, 5, 1]

13
Вы также можете использовать l.append(l.pop(0)). Он ненамного длиннее, но гораздо более читабелен.
coredumperror

Как я могу вместо этого переместить его в начало?

21

Если вы не знаете позицию элемента, вам может потребоваться сначала найти индекс:

old_index = list1.index(item)

затем переместите его:

list1.insert(new_index, list1.pop(old_index))

или ИМХО более чистый способ:

try:
  list1.remove(item)
  list1.insert(new_index, item)
except ValueError:
  pass

6
Я думаю, что я прав, когда съеживаюсь от вашего passутверждения ... никогда не скрывайте исключений - по умолчанию в примере, подобном этому, должно быть предоставление более чистого сообщения об ошибке или оператора печати ... raise ValueError(f'Unable to move item to {new_index}')или print(f'Moving item to {new_index} failed. List remains unchanged.'). Может быть, passбыло бы хорошо, если бы функция вызывалась try_to_move_itemили что-то в этом роде, чтобы было понятно, что операция может потерпеть неудачу.
flutefreak7 08

3

Решение очень простое, но вы должны знать индекс исходной позиции и индекс новой позиции:

list1[index1],list1[index2]=list1[index2],list1[index1]

8
Это обмен, а не ход.
juzzlin

0

Я разработал несколько методов перемещения элемента в том же списке с помощью timeit. Вот те, которые нужно использовать, если j> i:

┌──────────────────────────────────
│ 14.4usec │ x [i: i] = x.pop (j), │
│ 14.5usec │ x [i: i] = [x.pop (j)] │
│ 15.2usec │ x.insert (i, x.pop (j)) │
└──────────────────────────────────

и вот те, которые нужно использовать, если j <= i:

┌──────────┬─────────────────────────────
│ 14.4usec │ x [i: i] = x [j] ,; del x [j] │
│ 14.4usec │ x [i: i] = [x [j]]; del x [j] │
│ 15.4usec │ x.insert (i, x [j]); del x [j] │
└──────────┴─────────────────────────────

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.