มีวิธีการคลายแพ็กรายการในองค์ประกอบแรกและ "tail" ในคำสั่งเดียวหรือไม่?
ตัวอย่างเช่น:
>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
มีวิธีการคลายแพ็กรายการในองค์ประกอบแรกและ "tail" ในคำสั่งเดียวหรือไม่?
ตัวอย่างเช่น:
>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
คำตอบ:
ภายใต้ Python 3.x คุณสามารถทำได้อย่างดี:
>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
คุณลักษณะใหม่ใน 3.x คือการใช้ตัว*
ดำเนินการในการแกะกล่องเพื่อหมายถึงค่าพิเศษใด ๆ มีอธิบายไว้ในPEP 3132 - Extended Iterable Unpackingเอาออก นอกจากนี้ยังมีข้อดีของการทำงานกับการทำซ้ำใด ๆ ไม่ใช่แค่ลำดับ
นอกจากนี้ยังสามารถอ่านได้จริงๆ
ตามที่อธิบายไว้ใน PEP หากคุณต้องการทำสิ่งที่เทียบเท่าภายใต้ 2.x (โดยไม่ต้องสร้างรายการชั่วคราว) คุณต้องทำสิ่งนี้:
it = iter(iterable)
head, tail = next(it), list(it)
ตามที่ระบุไว้ในความคิดเห็นสิ่งนี้ยังให้โอกาสในการรับค่าเริ่มต้นhead
แทนที่จะโยนข้อยกเว้น หากคุณต้องการพฤติกรรมนี้ให้next()
ใช้อาร์กิวเมนต์ที่สองซึ่งเป็นทางเลือกพร้อมค่าเริ่มต้นดังนั้นnext(it, None)
จะให้คุณNone
ถ้าไม่มีองค์ประกอบส่วนหัว
โดยปกติหากคุณกำลังทำงานในรายการวิธีที่ง่ายที่สุดที่ไม่มีไวยากรณ์ 3.x คือ:
head, tail = seq[0], seq[1:]
__getitem__
/ __setitem__
เพื่อดำเนินการหางได้อย่างเฉื่อยชา แต่รายการในตัวไม่ทำ
python 3.x
>>> mylist = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head, tail = mylist[0], mylist[1:]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
สำหรับความซับซ้อนของhead,tail
การดำเนินการO (1) คุณควรใช้deque
อย่างไร
วิธีต่อไปนี้:
from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l
จะมีประโยชน์เมื่อคุณต้องวนซ้ำองค์ประกอบทั้งหมดของรายการ ตัวอย่างเช่นในการผสาน 2 พาร์ติชันแบบไร้เดียงสาในการเรียงลำดับการผสาน
head, tail = l.popleft(), l
คือ ~ O (1) head, tail = seq[0], seq[1:]
คือ O (n)
head = l.popleft()
และเป็นเพียงนามแฝงสำหรับtail
l
หากมีl
การtail
เปลี่ยนแปลงเปลี่ยนแปลงด้วย.
Python 2 โดยใช้ lambda
>>> head, tail = (lambda lst: (lst[0], lst[1:]))([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
head, tail = lst[0], lst[1:]
? ถ้า OP หมายถึงการใช้ตัวอักษรเขาก็สามารถแยกหัวและหางได้ด้วยตนเองhead, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]
lst = ...
ในบรรทัดก่อนหน้า) (2) การทำhead, tail = lst[0], lst[1:]
ใบเปิดรหัสผลข้างเคียง (พิจารณาhead, tail = get_list()[0], get_list()[1:]
) head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
และแตกต่างจากรูปแบบของสหกรณ์
การสร้างโซลูชัน Python 2 จาก @GarethLattyต่อไปนี้เป็นวิธีรับบรรทัดเดียวที่เทียบเท่าโดยไม่มีตัวแปรกลางใน Python 2
t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]
หากคุณต้องการให้เป็นข้อยกเว้น (เช่นรองรับรายการว่าง) ให้เพิ่ม:
t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]
หากคุณต้องการทำโดยไม่มีอัฒภาคให้ใช้:
h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]