ไข่ปลา […] หมายถึงอะไรในรายการ


196

ฉันกำลังเล่นอยู่ในงูหลาม ฉันใช้รหัสต่อไปนี้ใน IDLE:

p  = [1, 2]
p[1:1] = [p]
print p

ผลลัพธ์คือ:

[1, [...], 2]

นี่อะไรน่ะ[…]? ที่น่าสนใจตอนนี้ฉันสามารถใช้สิ่งนี้เป็นรายการของรายการสูงสุดถึงอนันต์คือ

p[1][1][1]....

ฉันสามารถเขียนข้างต้นตราบเท่าที่ฉันต้องการและมันจะยังคงทำงาน

แก้ไข:

  • มันเป็นตัวแทนในหน่วยความจำได้อย่างไร?
  • มันใช้อะไร? ตัวอย่างของบางกรณีที่มีประโยชน์จะเป็นประโยชน์
  • ลิงก์ใด ๆ ไปยังเอกสารอย่างเป็นทางการจะมีประโยชน์จริงๆ

ยังคงมองหาคำตอบสำหรับองค์ประกอบรายการที่ 1 และ 3 ของ EDIT
Aseem Bansal

7
ตัวอย่างที่ง่ายกว่าp = [1]; p[0] = pคือ
arshajii

6
ฉันคิดว่านี่เป็นสิ่งที่ซ้ำกันของ[…] (จุดไข่ปลา) ในรายการมีความหมายใน Python อย่างไร แม้ว่าคำถาม (และคำตอบ) จะดีกว่าในคำถามนี้
Martin Thoma

1
Dreampie เป็นสมาร์ท `>>> p [1: 1] = [p] >>> p 3: [1, <การเรียกซ้ำในรายการด้วย id = 3074777548>, 2] >>>` ให้รายละเอียดที่แน่นอน
Rahul Gautam

@RahulGautam p 3: [1, <Recursion on list with id=3074777548>, 2]ไม่ได้รับนี้ คุณทำงานอะไร
Aseem Bansal

คำตอบ:


112

หมายความว่าคุณสร้างรายการที่ไม่สิ้นสุดซ้อนอยู่ภายในตัวเองซึ่งไม่สามารถพิมพ์ได้ pประกอบด้วยpซึ่งมีp... และอื่น ๆ [...]สัญกรณ์เป็นวิธีที่จะช่วยให้คุณรู้เรื่องนี้และแจ้งให้ทราบว่ามันไม่สามารถเป็นตัวแทน! ดูคำตอบของ @ 6502 เพื่อดูภาพสวย ๆ ที่แสดงว่าเกิดอะไรขึ้น

ตอนนี้เกี่ยวกับสามรายการใหม่หลังจากที่คุณแก้ไข:

  • คำตอบนี้ดูเหมือนจะครอบคลุม
  • ลิงก์ของอิกนาชิโออธิบายการใช้งานที่เป็นไปได้บางอย่าง
  • นี่เป็นหัวข้อของการออกแบบโครงสร้างข้อมูลมากกว่าภาษาการเขียนโปรแกรมดังนั้นจึงไม่น่าจะมีการอ้างอิงใด ๆ ในเอกสารราชการของ Python

ดังนั้นมันใช้หน่วยความจำ infinte? ฉันรู้ว่ามันเป็นไปไม่ได้ มันเป็นตัวแทนและวิธีการใช้งานของมันคืออะไร?
Aseem Bansal

21
@Zel: องค์ประกอบของรายการเป็นการอ้างอิง องค์ประกอบที่สองคือการอ้างอิงไปยังรายการตัวเอง
Ignacio Vazquez-Abrams

2
Python ระบุว่าเป็นวงวนอ้างอิงที่ไม่สิ้นสุดดังนั้นจึงตัดสินใจตัดสั้น ๆ และไม่มันไม่ได้จริงๆที่มีประโยชน์นอกเหนือจากการทดลองทางความคิด :)
ÓscarLópez

2
มี ... การใช้งานไม่กี่อย่างสำหรับโครงสร้างแบบเรียกซ้ำ แต่ไม่มาก
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abrams ตัวอย่างบางส่วนจะมีประโยชน์
Aseem Bansal

316

นี่คือสิ่งที่รหัสของคุณสร้างขึ้น

ป้อนคำอธิบายรูปภาพที่นี่

เป็นรายการที่องค์ประกอบแรกและสุดท้ายชี้ไปที่ตัวเลขสองตัว (1 และ 2) และตำแหน่งที่องค์ประกอบกลางชี้ไปที่รายการนั้น

ใน Common Lisp เมื่อเปิดใช้งานการพิมพ์โครงสร้างแบบวงกลมวัตถุดังกล่าวจะถูกพิมพ์เป็น

#1=#(1 #1# 2)

หมายความว่ามีวัตถุ (ที่มีป้ายกำกับ 1 ด้วย#1=) ซึ่งเป็นเวกเตอร์ที่มีสามองค์ประกอบส่วนที่สองเป็นวัตถุ (อ้างอิงกลับด้วย#1#)

[...]ในหลามแทนคุณเพิ่งได้รับข้อมูลที่โครงสร้างเป็นวงกลม

ในกรณีเฉพาะนี้คำอธิบายไม่ชัดเจน (เป็นการย้อนหลังชี้ไปที่รายการ แต่มีเพียงหนึ่งรายการเท่านั้นดังนั้นจึงต้องเป็นรายการนั้น) ในกรณีอื่น ๆ อาจไม่ชัดเจนอย่างไรก็ตามตัวอย่างเช่น

[1, [2, [...], 3]]

การอ้างอิงย้อนหลังอาจชี้ไปที่ด้านนอกหรือรายการภายใน โครงสร้างที่แตกต่างกันทั้งสองนี้สามารถพิมพ์ด้วยวิธีเดียวกันได้

x = [1, [2, 3]]
x[1][1:1] = [x[1]]

y = [1, [2, 3]]
y[1][1:1] = [y]

print(x)
print(y)

และพวกเขาจะอยู่ในความทรงจำเป็น

ป้อนคำอธิบายรูปภาพที่นี่


คุณสามารถค้นหาเนื้อหาของ[1, [2, [...], 3]]เช่นนี้และx[1] = [2, [...], 3] y[1] = [2, 1, [...]], 3]นี่หมายความว่า x ประกอบด้วย 1 แล้วทำซ้ำ 2 วินาทีในขณะที่ y ประกอบด้วยสลับ 1 และ 2
pascalhein

2
@csharpler: แน่นอนคุณสามารถแยกความแตกต่างทั้งสองได้โดยการวิเคราะห์เนื้อหาอย่างไรก็ตามพวกเขาจะถูกพิมพ์ด้วยการเป็นตัวแทนเดียวกัน ในรูปแบบที่พบบ่อยชัดแทนพวกเขาจะเป็น#(1 #1=#(2 #1# 3))สำหรับxและสำหรับ#1=#(1 #(2 #1# 3)) y
6502

5
@BurhanKhalid: inkscape เป็นครั้งแรกและขลิบด้ายที่สอง (เพราะฉันทิ้ง SVG)
6502

1
@csharpler: คุณไม่สามารถสร้าง "infinite list" ใน Python เพราะรายการนั้นเป็นอาร์เรย์ที่ปรับขนาดได้จริงไม่ใช่รายการที่เชื่อมโยง "รายการที่ไม่มีที่สิ้นสุด" ใน Common #1=(1 . #1#)เสียงกระเพื่อมแทนอาจจะสร้างขึ้นด้วย
6502

1
+ หากคุณต้องการวาด acsii-diagram เช่นลองนี้: Asiiflow
Grijesh Chauhan

23

สำหรับคำถาม "การใช้งานอะไร" นี่เป็นตัวอย่างที่เป็นรูปธรรม

การลดกราฟเป็นกลยุทธ์การประเมินผลที่ใช้ในการแปลภาษาคอมพิวเตอร์ นี่เป็นกลยุทธ์ทั่วไปสำหรับการประเมินผลที่ขี้เกียจโดยเฉพาะภาษาที่ใช้งานได้

จุดเริ่มต้นคือการสร้างกราฟที่แสดงถึงลำดับของ "ขั้นตอน" ที่โปรแกรมจะดำเนินการ ขึ้นอยู่กับโครงสร้างการควบคุมที่ใช้ในโปรแกรมนั้นสิ่งนี้อาจนำไปสู่กราฟวงจร (เนื่องจากโปรแกรมมีลูป "ถาวร" บางประเภท - หรือใช้การเรียกซ้ำซึ่งมี "ความลึก" ซึ่งจะทราบเวลาการประเมินแต่ไม่ใช่กราฟ -เวลาที่สร้าง ) ...

เพื่อที่จะเป็นตัวแทนของกราฟเช่นนี้คุณต้องไม่มีที่สิ้นสุด "โครงสร้างข้อมูล" (เรียกว่าบางครั้งrecursiveโครงสร้างข้อมูล) เช่นเดียวกับคนที่คุณสังเกตเห็น โดยปกติแล้วจะซับซ้อนกว่าเล็กน้อย

หากคุณมีความสนใจในหัวข้อดังกล่าวต่อไปนี้คือการบรรยายในหัวข้อนั้น:
http://undergraduate.csse.uwa.edu.au/units/CITS3211/lectureNotes/14.pdf


7

เราทำสิ่งนี้ตลอดเวลาในการเขียนโปรแกรมเชิงวัตถุ หากวัตถุสองชิ้นอ้างถึงกันและกันไม่ว่าทางตรงหรือทางอ้อมทั้งสองเป็นโครงสร้างแบบเรียกซ้ำแบบไม่สิ้นสุด (หรือทั้งสองส่วนของโครงสร้างแบบเรียกซ้ำแบบไม่มีที่สิ้นสุดทั้งสองนี้ขึ้นอยู่กับว่าคุณมองอย่างไร) นั่นเป็นเหตุผลที่คุณไม่เห็นสิ่งนี้มากนักในรายการแบบดั้งเดิม - เพราะเรามักจะอธิบายแนวคิดว่า "วัตถุ" ที่เชื่อมโยงถึงกันได้ดีกว่ารายการที่ไม่มีที่สิ้นสุด

นอกจากนี้คุณยังสามารถรับ...พจนานุกรมแบบเรียกซ้ำไม่สิ้นสุด สมมติว่าคุณต้องการพจนานุกรมของมุมของสามเหลี่ยมที่แต่ละค่าเป็นพจนานุกรมของอีกมุมหนึ่งที่เชื่อมต่อกับมุมนั้น คุณสามารถตั้งค่าแบบนี้:

a = {}
b = {}
c = {}
triangle = {"a": a, "b": b, "c": c}
a["b"] = b
a["c"] = c
b["a"] = a
b["c"] = c
c["a"] = a
c["b"] = b

ตอนนี้ถ้าคุณพิมพ์triangle(หรือaหรือbหรือcสำหรับเรื่องนั้น) คุณจะเห็นว่ามันเต็ม{...}เพราะทั้งสองมุมนั้นหมายถึงการกลับมาหากัน


ตัวอย่างพจนานุกรมที่ง่ายขึ้น:a = {}; a['a'] = a; print a['a']['a']['a']
650654

สำหรับฉันแทนที่จะเป็น "... " มันแสดงให้เห็นว่า "<การเรียกซ้ำตามคำสั่งด้วย id = ___>"
โซโลมอน Ucko

@SolomonUcko คุณอาจใช้ IPython ซึ่งใช้pprintในการพิมพ์สิ่งต่าง ๆโดยอัตโนมัติ หากคุณพิมพ์%pprintเพื่อสลับการพิมพ์ที่ไม่สวยออกมามันจะปรากฏ...ขึ้น
nmclean

4

ดังที่ฉันเข้าใจนี่คือตัวอย่างของจุดคงที่

p  = [1, 2]
p[1:1] = [p]
f = lambda x:x[1]
f(p)==p
f(f(p))==p

ฉันไม่สามารถเข้าใจสิ่งนี้ได้ พยายามเรียกใช้คำสั่งเหล่านี้ แต่มีข้อผิดพลาด
Aseem Bansal

@Zel: คุณต้องเพิ่มรหัส OPs ก่อนจึงจะมีการประกาศ p
Inkane

1
@Zel: ดีฉันไม่แน่ใจว่าเป็นประโยชน์ตัวเอง แต่ Firegun บอกว่า p (และดังนั้น p [1], แสดงเป็น [... ]) เป็น fixpoint ของฟังก์ชัน f IMHO นี่เป็นคำตอบที่เป็นไปได้ของคำถาม "อะไรคือ [... ]?" ในกรณีนี้.
Inkane

1
ฉันมีปัญหาข้อผิดพลาดเดียวกันเพราะฉันลองตัวอย่างนี้หลังจากลองใช้p = [1]; p[0] = pตัวอย่างที่ง่ายกว่าซึ่งต้องf = lambda x:x[0]ใช้งาน มันเป็นตัวอย่างของจุดแก้ไข แต่ฉันยังไม่สามารถดูว่าการรู้เรื่องนี้มีประโยชน์อย่างไร มูลค่าที่แท้จริงของจุดแก้ไขนั้นมาจากจุดอื่นในลักษณะวนซ้ำหรือซ้ำ ตัวอย่างที่แสดงวิธีการใช้โครงสร้างรายการของคำถามต้นฉบับเพื่อสร้าง Y combinator จะเป็นประโยชน์หากเป็นไปได้
dansalmo

1
q = lambda: qทำให้แลมบ์ดาเรียกได้ไม่สิ้นสุด
whackamadoodle3000

-2

ชื่อของวัตถุพิเศษนั้นคือ Ellipsis ฉันเดาว่ามันถูกนำไปใช้เป็นวัตถุเดี่ยวใน Python intepreter / VM - เช่น None --- Sentinel แปลก ๆ อย่างที่คุณเห็นมันเป็นวิธีที่ Python จะแสดงการอ้างอิงของรายการภายในตัวมันเอง


ดูเหมือนจะไม่มีทางที่จะยกตัวอย่างวัตถุ Ellipsis โดยตรง ชื่อจะไม่ถูกเปิดเผยผ่านอินเทอร์เฟซของ Builtins ดังนั้นคุณสามารถดูการอ้างอิงถึงคำศัพท์ในข้อผิดพลาดบางอย่าง (ยกข้อยกเว้น) ตัวอย่างเช่นถ้าคุณพยายามที่จะแยกรายการโดยใช้จุดไข่ปลาเป็นดัชนี แต่คุณสามารถพูดได้ว่า: el = Ellipsis () หรืออะไรทำนองนั้น (ที่ฉันเคยพบ)
จิมเดนนิส

9
อันนี้ไม่มีอะไรเกี่ยวข้องกับวัตถุ Ellipsis มันเป็นเพียงสตริงตัวอักษร "[... ]" ซึ่งถูกพิมพ์เมื่อตรวจพบรอบในระหว่างการพิมพ์รายการ ดูรหัส: hg.python.org/cpython/file/84d6c1c0665e/Objects/ …
Jeremy Sharpe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.