ใครช่วยอธิบายพฤติกรรมของคำสั่งว่างในนิพจน์ตัวสร้างหลามได้ไหม [ทำซ้ำ]

เพื่อนและฉันกำลังคุยกันเรื่องที่เกี่ยวข้องกับการจัดการหน่วยความจำใน Python เมื่อเราสะดุดกับพฤติกรรมด้านล่าง:

In [46]: l = ({} for _ in range(6))

In [47]: [ id(i) for i in l]
Out[47]:
[4371243648, # A
 4371245048, # B
 4371243648, # A
 4371245048, # B
 4371243648, # etc.
 4371245048]

สิ่งที่น่าประหลาดใจก็คือ ดูเหมือนว่าเราไม่มีพฤติกรรมที่กำหนดไว้อย่างชัดเจน: dict ไม่ใช่สิ่งใหม่ในแต่ละครั้ง และไม่มีการอ้างอิงเดียวกันในแต่ละครั้ง

ยิ่งไปกว่านั้น เรามีพฤติกรรมแปลกๆ นี้ (ไม่ใช่โค้ดถูกเรียกใช้ในล่ามระหว่างตัวอย่างทั้งสองนี้)

In [48]: m = ({} for _ in range(6))

In [49]: [ id(i) for i in m]
Out[49]:
[4371154376, # C
 4371245048, # B (same B as above!)
 4371154376, # C
 4371245048, # B
 4371154376,
 4371245048]

ใครสามารถอธิบายพฤติกรรมนี้ได้บ้าง การใช้รายการความเข้าใจ (l = [{} for _ in range(6)]) จะแสดงที่อยู่ที่แตกต่างกันสำหรับแต่ละ dict


person sitaktif    schedule 10.03.2015    source แหล่งที่มา
comment
คำถามนี้อาจทำให้คุณมีความคิดที่ดีเกี่ยวกับสิ่งที่เกิดขึ้น   -  person bvidal    schedule 10.03.2015
comment
คุณได้อ่าน id() เอกสารประกอบเกี่ยวกับฟังก์ชัน แล้วหรือยัง คุณพลาดบางสิ่งที่สำคัญไปที่นั่น   -  person Martijn Pieters    schedule 10.03.2015
comment
@MartijnPieters ฉันไม่แปลกใจเลยที่ id() นำหมายเลขเดิมกลับมาใช้ซ้ำ ฉันรู้สึกประหลาดใจกับใบหน้าที่มันนำหมายเลขเดิมกลับมาใช้ใหม่ ในขณะที่ฉันยังคงอ้างอิงถึงมัน (ซึ่งเป็นความผิดพลาดของฉัน)   -  person sitaktif    schedule 10.03.2015
comment
@sitaktif: ใช่แล้ว คุณไม่ได้เก็บการอ้างอิงใด ๆ ไปยังวัตถุ {} ที่คุณสร้าง เครื่องกำเนิดสร้างมันขึ้นมา แต่ไม่ได้อ้างอิงมันในภายหลัง   -  person Martijn Pieters    schedule 10.03.2015
comment
@sitaktif: ฉันคิดว่าคุณผิดที่นี่: คำสั่งนั้นไม่ใช่สิ่งใหม่ในแต่ละครั้งหรือการอ้างอิงเดียวกันในแต่ละครั้ง เป็น คำสั่งใหม่ทุกครั้ง นิพจน์ทางซ้ายในนิพจน์ตัวสร้างจะถูกประเมินใหม่ในแต่ละการวนซ้ำ   -  person Martijn Pieters    schedule 10.03.2015
comment
@MartijnPieters อย่างแน่นอน   -  person sitaktif    schedule 11.03.2015


คำตอบ (1)


พจนานุกรมจะถูกทำลายทันทีที่ผู้สร้างไม่ได้อ้างอิงอีกต่อไป คุณกำลังเปรียบเทียบ ID ของวัตถุที่ไม่ทำงาน และ ID สามารถนำมาใช้ซ้ำได้

person Kevin    schedule 10.03.2015
comment
นี่คือสิ่งที่ฉันพลาดไป - ความจริงที่ว่าด้วยตัวสร้างฉันจะสูญเสียการอ้างอิงไปยังรายการนั้น ขอบคุณ! - person sitaktif; 10.03.2015