แทรกองค์ประกอบที่ดัชนีเฉพาะในรายการและส่งคืนรายการที่อัปเดต


105

ฉันมีสิ่งนี้:

>>> 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]

มีวิธีใดบ้างที่ฉันจะได้รับรายการที่อัปเดตเป็นผลลัพธ์แทนที่จะอัปเดตรายการเดิมแทน


11
b = a[:].insert(2,3)ดูเหมือนจะค่อนข้างสั้นไม่มีผลกับรายการต้นฉบับและเป็นคำอธิบายที่ค่อนข้างชัดเจน
mkoistinen

6
@mkoistinen มันไม่ได้ผลสำหรับฉัน >>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
SparkAndShine

คำตอบ:


91

l.insert(index, obj)ไม่ได้คืนอะไรเลย มันแค่ปรับปรุงรายการ

b = a[:index] + [obj] + a[index:]ในฐานะที่กรมสรรพากรกล่าวว่าที่คุณสามารถทำได้ อย่างไรก็ตามอีกวิธีหนึ่งคือ:

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

56
หากคุณไม่สามารถทนต่อรหัสที่อ่านได้ 3 บรรทัดให้ใส่ในฟังก์ชันและเรียกมัน
IceArdor

60

แนวทางที่มีประสิทธิภาพสูงสุด

นอกจากนี้คุณยังสามารถแทรกองค์ประกอบโดยใช้การสร้างดัชนีชิ้นในรายการ ตัวอย่างเช่น:

>>> 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 the original list

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

สำหรับการแทรกหลายองค์ประกอบเข้าด้วยกันในดัชนีที่กำหนดสิ่งที่คุณต้องทำคือใช้listองค์ประกอบหลายรายการที่คุณต้องการแทรก ตัวอย่างเช่น:

>>> 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]

ทางเลือกในการใช้ความเข้าใจรายการ (แต่ช้ามากในแง่ของประสิทธิภาพ) :

อีกทางเลือกหนึ่งคือสามารถทำได้โดยใช้ความเข้าใจในรายการด้วยenumerateเช่นกัน (แต่โปรดอย่าทำแบบนี้เป็นเพียงภาพประกอบ) :

>>> 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]

การเปรียบเทียบประสิทธิภาพของโซลูชันทั้งหมด

นี่คือการtimeitเปรียบเทียบคำตอบทั้งหมดพร้อมรายการองค์ประกอบ 1,000 รายการสำหรับ Python 3.4.5:

  • คำตอบของฉันโดยใช้การแทรกแบบแบ่งส่วน - เร็วที่สุด (3.08 µsec ต่อวง)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b[500:500] = [3]"
     100000 loops, best of 3: 3.08 µsec per loop
    
  • คำตอบที่ยอมรับของ ATOzTOAโดยพิจารณาจากการรวมรายการแบบแบ่งส่วน - วินาที (6.71 µsec ต่อวง)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:500] + [3] + a[500:]"
     100000 loops, best of 3: 6.71 µsec per loop
    
  • คำตอบของ Rushy Panchal ที่มีผู้โหวตมากที่สุดโดยใช้list.insert(...)- อันดับสาม (26.5 usec ต่อวง)

     python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
     10000 loops, best of 3: 26.5 µsec per loop
    
  • คำตอบของฉันพร้อมความเข้าใจในรายการและenumerate- ประการที่สี่ (ช้ามาก 168 µsec ต่อวง)

     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 µsec per loop
    

2
ผมชอบผลนี้เพราะมันได้อย่างง่ายดายขยายไปถึงการแก้ปัญหาสิ่งที่ถ้าผมต้องการที่จะใส่ค่า3, 3.5ลงในรายการที่ (ตามลำดับ) a[2:2] = [3,3.5]-> เรียบร้อยมาก
minillinim

1
[2: 2] = a_list ทำงานอย่างไร โดยทั่วไปแล้ว [2: 2] จะเริ่มต้นจากดัชนีที่ 2 ถึงดัชนีที่ 1 (2-1) แต่ในทิศทางไปข้างหน้าซึ่งหมายถึงรายการ [] ที่ว่างเปล่า มันขยายได้อย่างไร? ถ้าเราทำ [2: 3: -1] มันไม่ได้ผล
SamCodes

คำตอบที่ดี ฉันสงสัยว่าความซับซ้อนของทางเลือกที่ดีที่สุดคือ O (1) หรือไม่? ถ้าเป็นเช่นนั้นทำไม?
Lerner Zhang

คำตอบนี้ต้องได้รับการอัปเดต ครั้งหนึ่งฉันไม่สามารถทำซ้ำการกำหนดเวลาที่รายงานได้แม้จะใช้ Python 3.4 (ฉันได้รับปัจจัย 2 ระหว่างlist.insertและการกำหนดชิ้นส่วน) และใน Python 3.8 ความแตกต่างนี้ก็หายไปโดยสิ้นเชิง วิธีที่ชัดเจนที่สุดในการแทรกองค์ประกอบคือการใช้list.insertอย่างชัดเจน
a_guest

@Moinuddin Quadri โซลูชันแรกทำงานอย่างไร? คุณช่วยอธิบายหรือให้ลิงค์ได้ไหม
Crispy13

39

สั้นที่สุดที่ฉันได้รับ: 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]

จำนวนบรรทัดของโค้ดไม่ใช่ตัวชี้วัดคุณภาพของโค้ดที่ดี แนวทางนี้มีข้อบกพร่องเนื่องจากเหตุผลด้านประสิทธิภาพและความสามารถในการอ่าน
a_guest

0

วิธีที่สะอาดที่สุดคือคัดลอกรายการจากนั้นใส่วัตถุลงในสำเนา ใน Python 3 สามารถทำได้ผ่านlist.copy:

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

ใน Python 2 การคัดลอกรายการสามารถทำได้ผ่านnew = old[:](ซึ่งใช้ได้กับ Python 3 ด้วย)

ในแง่ของประสิทธิภาพไม่มีความแตกต่างกับวิธีการอื่น ๆ ที่เสนอ:

$ 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 µsec per loop
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b[500:500] = (3,)"
100000 loops, best of 5: 2.76 µsec per loop

-1

ใช้งูหลามรายการแทรก () วิธีการ การใช้งาน:

# ซินแท๊กซ์

ไวยากรณ์สำหรับวิธีการแทรก () -

list.insert(index, obj)

# พารามิเตอร์

  • ดัชนี - นี่คือดัชนีที่ต้องใส่วัตถุ obj
  • obj - นี่คือวัตถุที่จะแทรกลงในรายการที่กำหนด

#Return Value วิธีนี้ไม่ส่งคืนค่าใด ๆ แต่จะแทรกองค์ประกอบที่กำหนดในดัชนีที่กำหนด

ตัวอย่าง:

a = [1,2,4,5]

a.insert(2,3)

print(a)

ผลตอบแทน [1, 2, 3, 4, 5]


2
สิ่งนี้ไม่ตอบคำถาม
Gustav Bertram

5
คำถามมีความเฉพาะเจาะจง: Is there anyway I can get the updated list as result, instead of updating the original list in place?คำตอบของคุณตรงกันข้าม
Laszlowaty
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.