Di chuyển một mục bên trong danh sách?


104

Trong Python, làm cách nào để di chuyển một mục đến một chỉ mục xác định trong danh sách?

Câu trả lời:


160

Sử dụng insertphương pháp của một danh sách:

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

Ngoài ra, bạn có thể sử dụng ký hiệu lát cắt:

l[index:index] = [item]

Nếu bạn muốn di chuyển một mục đã có trong danh sách đến vị trí được chỉ định, bạn sẽ phải xóa nó và chèn nó vào vị trí mới:

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

22
Chỉ cần lưu ý rằng việc di chuyển một mục đã có trong danh sách bằng phương thức insert / pop sẽ có các hành vi khác nhau tùy thuộc vào việc bạn đang di chuyển về phía trước hoặc phía sau danh sách. Di chuyển sang trái bạn chèn trước đối tượng bạn đã chọn. Di chuyển ra phía sau mà bạn chèn sau mục bạn đã chọn. Kiểm tra việc di chuyển đến cuối danh sách (lỗi chỉ mục).
MKaras

Làm thế nào để di chuyển nhiều phần tử? Cho một danh sách a = [1,2,3,4,5,6,7,8,9], cách biến đổi nó thành [1,2, [3,4,5], 6,7,8,9 ]? Điều này có thể được thực hiện trong một bước hoặc với một danh sách hiểu không?
g33kz0r

@MKaras Tôi đã thử nghiệm điều này với Python 3.5 và bạn CÓ THỂ chèn vào last index + 1mà không bị lỗi. Phần tử chỉ được thêm vào danh sách trong trường hợp đó.
user2061057,

@ user2061057 là đúng :) ngay cả các chỉ mục lớn cũng sẽ dẫn đến những thứ được chèn vào cuối. a.insert(99999, 1) In [14]: a Out[14]: [...., 1]
lee penkman,

1
Đối với những người đang cố gắng sử dụng chỉ mục -1 để chèn mục vào cuối, bạn phải sử dụng len (l) để thay thế.
nda

31

Một giải pháp ngắn hơn một chút, chỉ di chuyển mục đến cuối, không phải ở bất kỳ đâu là:

l += [l.pop(0)]

Ví dụ:

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

13
Bạn cũng có thể sử dụng l.append(l.pop(0)). Nó chỉ dài hơn một chút, nhưng nó dễ đọc hơn nhiều.
coredumperror

Làm cách nào để tôi có thể chuyển nó về đầu thay thế?

19

Nếu bạn không biết vị trí của mục, trước tiên bạn có thể cần tìm chỉ mục:

old_index = list1.index(item)

sau đó di chuyển nó:

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

hoặc IMHO một cách rõ ràng hơn:

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

6
Tôi nghĩ rằng tôi đúng khi passphát biểu ý kiến của bạn ... không bao giờ ẩn các ngoại lệ - điều mặc định trong một ví dụ như thế này phải là cung cấp một câu lệnh lỗi rõ ràng hơn hoặc câu lệnh in ... raise ValueError(f'Unable to move item to {new_index}')hoặc print(f'Moving item to {new_index} failed. List remains unchanged.'). Có lẽ passsẽ ổn nếu trong một hàm được gọi try_to_move_itemhoặc một cái gì đó để nó hiểu rằng hoạt động có thể thất bại một cách âm thầm.
sáofreak7

3

Một giải pháp rất đơn giản, nhưng bạn phải biết chỉ số của vị trí ban đầu và chỉ số của vị trí mới:

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

6
Đây là một sự hoán đổi, không phải là một động thái.
juzzlin

0

Tôi đã mô tả một số phương pháp để di chuyển một mục trong cùng một danh sách với thời gian. Dưới đây là những cái để sử dụng nếu 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)) │
└───────────┴────────────────────────┘

và đây là những cái để sử dụng nếu 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] │
└───────────┴────────────────────────────

Không phải là một sự khác biệt lớn nếu bạn chỉ sử dụng nó một vài lần, nhưng nếu bạn làm những việc nặng như phân loại thủ công, điều quan trọng là phải lấy nhanh nhất. Nếu không, tôi khuyên bạn chỉ nên lấy cuốn mà bạn cho là dễ đọc nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.