Chèn một phần tử tại chỉ mục cụ thể trong danh sách và trả về danh sách đã cập nhật


99

Tôi có cái này:

>>> a = [1, 2, 4]
>>> print a
[1, 2, 4]

>>> print a.insert(2, 3)
None

>>> print a
[1, 2, 3, 4]

>>> b = a.insert(3, 6)
>>> print b
None

>>> print a
[1, 2, 3, 6, 4]

Có cách nào tôi có thể nhận được danh sách cập nhật, thay vì cập nhật danh sách ban đầu tại chỗ không?


11
b = a[:].insert(2,3)có vẻ khá ngắn, không ảnh hưởng đến danh sách ban đầu và khá mô tả.
mkoistinen

6
@mkoistinen Nó không hiệu quả với tôi. >>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
SparkAndShine

Câu trả lời:


89

l.insert(index, obj)không thực sự trả lại bất cứ điều gì, nó chỉ cập nhật danh sách. Như ATO đã nói, bạn có thể làm được b = a[:index] + [obj] + a[index:]. Tuy nhiên, một cách khác là:

a = [1, 2, 4]
b = a[:]
b.insert(2, 3)

56
Nếu bạn không thể chấp nhận 3 dòng mã có thể đọc được, hãy đặt nó vào một hàm và gọi nó.
IceArdor

53

Cách tiếp cận Hiệu quả nhất

Bạn cũng có thể chèn phần tử bằng cách sử dụng lập chỉ mục lát trong danh sách. Ví dụ:

>>> a = [1, 2, 4]
>>> insert_at = 2  # index at which you want to insert item

>>> b = a[:]   # created copy of list "a" as "b"
               # skip this step if you are ok with modifying original list

>>> b[insert_at:insert_at] = [3]  # insert "3" within "b"
>>> b
[1, 2, 3, 4]

Để chèn nhiều phần tử với nhau tại một chỉ mục nhất định , tất cả những gì bạn cần làm là sử dụng một listtrong nhiều phần tử mà bạn muốn chèn. Ví dụ:

>>> a = [1, 2, 4]
>>> insert_at = 2   # index starting from which multiple elements will be inserted 

# List of elements that you want to insert together at "index_at" (above) position
>>> insert_elements = [3, 5, 6]

>>> a[insert_at:insert_at] = insert_elements
>>> a   # [3, 5, 6] are inserted together in `a` starting at index "2"
[1, 2, 3, 5, 6, 4]

Thay thế bằng cách sử dụng Tính năng hiểu danh sách (nhưng rất chậm về mặt hiệu suất) :

Là một thay thế, nó có thể đạt được bằng danh sách hiểu với enumeratequá. (Nhưng xin đừng làm theo cách này. Nó chỉ mang tính chất minh họa) :

>>> a = [1, 2, 4]
>>> insert_at = 2

>>> b = [y for i, x in enumerate(a) for y in ((3, x) if i == insert_at else (x, ))]
>>> b
[1, 2, 3, 4]

So sánh hiệu suất của tất cả các giải pháp

Dưới đây là timeitso sánh tất cả các câu trả lời với danh sách 1000 phần tử cho Python 3.4.5:

  • Câu trả lời của tôi bằng cách sử dụng chèn cắt lát - Nhanh nhất (3.08 usec mỗi vòng lặp)

    mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b[500:500] = [3]"
    100000 loops, best of 3: 3.08 usec per loop
  • Câu trả lời được chấp nhận của ATOzTOA dựa trên việc hợp nhất các danh sách được chia nhỏ - Thứ hai (6,71 usec mỗi vòng lặp)

    mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:500] + [3] + a[500:]"
    100000 loops, best of 3: 6.71 usec per loop
  • Câu trả lời của Rushy Panchal với nhiều phiếu bầu nhất bằng cách sử dụnglist.insert(...)- Thứ ba (26,5 usec mỗi vòng lặp)

    python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
    10000 loops, best of 3: 26.5 usec per loop
  • Câu trả lời của tôi với Khả năng hiểu danh sáchenumerate- Thứ tư (rất chậm với 168 usec mỗi vòng lặp)

    mquadri$ python3 -m timeit -s "a = list(range(1000))" "[y for i, x in enumerate(a) for y in ((3, x) if i == 500 else (x, )) ]"
    10000 loops, best of 3: 168 usec per loop

2
Tôi thực sự thích kết quả này vì nó dễ dàng mở rộng để giải quyết vấn đề, nếu tôi muốn chèn các giá trị 3, 3.5vào danh sách đó (theo thứ tự) -> a[2:2] = [3,3.5]. Rất gọn gàng
minillinim

1
A [2: 2] = a_list hoạt động như thế nào? a [2: 2] về cơ bản bắt đầu từ chỉ mục thứ 2 đến chỉ mục thứ nhất (2-1) nhưng theo hướng chuyển tiếp có nghĩa là danh sách [] trống. Làm thế nào để nó mở rộng? Nếu chúng ta làm [2: 3: -1] thì nó không hoạt động.
SamCodes

Câu trả lời chính xác. Tôi tự hỏi nếu độ phức tạp của sự lựa chọn tốt nhất là O (1)? Nếu vậy, tại sao?
Lerner Zhang

Câu trả lời này cần được cập nhật. Vì một lần tôi không thể tạo lại thời gian được báo cáo ngay cả với Python 3.4 (tôi nhận được hệ số 2 giữa list.insertvà gán lát cắt) và trên Python 3.8, sự khác biệt này đã biến mất hoàn toàn. Cách rõ ràng nhất để chèn một phần tử là sử dụng list.insert, hiển nhiên.
a_guest

39

Ngắn nhất tôi có: b = a[:2] + [3] + a[2:]

>>> 
>>> a = [1, 2, 4]
>>> print a
[1, 2, 4]
>>> b = a[:2] + [3] + a[2:]
>>> print a
[1, 2, 4]
>>> print b
[1, 2, 3, 4]

Số dòng mã không phải là thước đo tốt để đánh giá chất lượng mã. Cách tiếp cận này có sai sót vì cả lý do hiệu suất và khả năng đọc.
a_guest

0

Cách tiếp cận rõ ràng nhất là sao chép danh sách và sau đó chèn đối tượng vào bản sao. Trên Python 3, điều này có thể được thực hiện thông qua list.copy:

new = old.copy()
new.insert(index, value)

Trên Python 2, việc sao chép danh sách có thể đạt được thông qua new = old[:](điều này cũng hoạt động trên Python 3).

Về mặt hiệu suất, không có sự khác biệt so với các phương pháp được đề xuất khác:

$ python --version
Python 3.8.1
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b.insert(500, 3)"
100000 loops, best of 5: 2.84 usec per loop
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b[500:500] = (3,)"
100000 loops, best of 5: 2.76 usec per loop

-1

Sử dụng phương thức insert () list trong Python . Sử dụng:

Cú pháp

Sau đây là cú pháp cho phương thức insert ():

list.insert(index, obj)

Thông số

  • index - Đây là Chỉ mục nơi đối tượng cần được chèn vào.
  • obj - Đây là Đối tượng được chèn vào danh sách đã cho.

Giá trị trả lại

Phương thức này không trả về bất kỳ giá trị nào nhưng nó sẽ chèn phần tử đã cho vào chỉ mục đã cho.

Thí dụ:

a = [1,2,4,5]

a.insert(2,3)

print(a)

Lợi nhuận [1, 2, 3, 4, 5]


1
Điều này không trả lời câu hỏi.
Gustav Bertram

4
Câu hỏi cụ thể: Is there anyway I can get the updated list as result, instead of updating the original list in place?Câu trả lời của bạn ngược lại.
Laszlowaty
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.