ควรใช้ iteritems () แทนรายการ () เมื่อใด


153

มันถูกต้องตามกฎหมายที่จะใช้items()แทนiteritems()ในทุกสถานที่? ทำไมiteritems()ลบออกจาก Python 3 ดูเหมือนว่าเป็นวิธีที่ยอดเยี่ยมและมีประโยชน์ อะไรคือเหตุผลเบื้องหลัง

แก้ไข:เพื่อให้ชัดเจนฉันต้องการทราบว่าสำนวนที่ถูกต้องสำหรับการวนซ้ำในพจนานุกรมในลักษณะที่คล้ายกับตัวสร้าง (รายการเดียวในแต่ละครั้งไม่ใช่ทุกหน่วยความจำ) ในวิธีที่เข้ากันได้กับทั้ง Python 2 และ Python 3 ?

คำตอบ:


148

ใน Python 2.x - .items()ส่งคืนรายการคู่ (คีย์, ค่า) ใน Python 3.x .items()ตอนนี้เป็นitemviewออบเจกต์ซึ่งมีพฤติกรรมแตกต่างกันดังนั้นจึงต้องมีการวนซ้ำหรือปรากฏเป็นรูปเป็นร่าง ... ดังนั้นlist(dict.items())จำเป็นสำหรับสิ่งที่อยู่dict.items()ใน Python 2.x

งูหลาม 2.7 นอกจากนี้ยังมีบิตของการกลับมาพอร์ตสำหรับการจัดการที่สำคัญในการที่คุณมีviewkeys, viewitemsและviewvaluesวิธีการที่เป็นประโยชน์มากที่สุดviewkeysซึ่งมีลักษณะการทำงานมากขึ้นเช่นset(ซึ่งคุณคาดหวังจากdict)

ตัวอย่างง่ายๆ:

common_keys = list(dict_a.viewkeys() & dict_b.viewkeys())

จะให้รายการของคีย์ทั่วไป แต่อีกครั้งใน Python 3.x - ใช้.keys()แทน

Python 3.x โดยทั่วไปถูกทำให้เป็น "ขี้เกียจ" มากกว่า - mapตอนนี้คือประสิทธิภาพitertools.imapแล้วzipคือitertools.izipเป็นต้น


96

dict.iteritemsถูกลบออกเนื่องจากdict.itemsในขณะนี้ไม่สิ่งdict.iteritemsได้ในหลาม 2.x itemviewและแม้กระทั่งการปรับปรุงมันบิตโดยการทำให้มันเป็น



9

เนื่องจากเอกสารพจนานุกรมสำหรับpython 2และpython 3จะบอกคุณใน python 2 itemsส่งคืนรายการในขณะที่iteritemsส่งคืนตัววนซ้ำ

ใน python 3 itemsส่งคืนมุมมองซึ่งค่อนข้างเหมือนกับตัววนซ้ำ

หากคุณใช้ python 2 คุณอาจต้องการผู้ใช้iteritemsหากคุณกำลังใช้พจนานุกรมขนาดใหญ่และสิ่งที่คุณต้องทำก็คือวนซ้ำไอเท็ม (ไม่จำเป็นต้องคัดลอกไปยังรายการ)


ฉันเข้าใจว่าiteritemsเป็นตัววนซ้ำซึ่งเป็นเหตุผลว่าทำไมจึงมีประโยชน์ ฉันแทบจะไม่ต้องการย้ำพจนานุกรมเป็นรายการ ดังนั้นวิธีที่ถูกต้องในการย้ำกับพจนานุกรมด้วยตัวสร้างสิ่งที่ชอบในวิธีที่เข้ากันได้กับ Python 2 และ 3 คืออะไร?

3
@ user248237 for key in some_dictทำงานได้ทั้งบน - และ2to3เครื่องมือที่จะแปลiteritems()ไปitems()แล้ว ...
จอนเคลเมนท์

1
@ JonClements: ยุติธรรมพอ แต่ฉันคิดเสมอว่าfor k in d: d[k]เป็น verbose / unpythonic โดยไม่จำเป็น

6

เช่นเดียวกับ @Wessie สังเกตdict.iteritems, dict.iterkeysและdict.itervalues(ซึ่งกลับiteratorใน Python2.x) เช่นเดียวกับdict.viewitems, dict.viewkeysและdict.viewvalues(ซึ่งกลับมาดูวัตถุใน Python2.x) ถูกถอดออกในทุก Python3.x

และdict.items, dict.keysและdict.valuesใช้ในการส่งคืนสำเนาของรายการพจนานุกรมใน Python2.x ตอนนี้กลับมุมมองวัตถุใน Python3.x, แต่พวกเขายังคงไม่เหมือนกับiterator

หากคุณต้องการส่งคืนตัววนซ้ำใน Python3.x ให้ใช้iter(dictview):

$ python3.3

>>> d = {'one':'1', 'two':'2'}
>>> type(d.items())
<class 'dict_items'>
>>>
>>> type(d.keys())
<class 'dict_keys'>
>>>
>>>
>>> ii = iter(d.items())
>>> type(ii)
<class 'dict_itemiterator'>
>>>
>>> ik = iter(d.keys())
>>> type(ik)
<class 'dict_keyiterator'>

ซึ่งมีประสิทธิภาพมากกว่าเมื่อต้องการค้นหาแบบผกผัน ดูวัตถุหรือตัววนซ้ำ?
อายุการใช้งาน

6

คุณไม่สามารถใช้itemsแทนiteritemsในสถานที่ทั้งหมดใน Python ตัวอย่างเช่นรหัสต่อไปนี้:

class C:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.iteritems()

>>> c = C(dict(a=1, b=2, c=3))
>>> [v for v in c]
[('a', 1), ('c', 3), ('b', 2)]

จะแตกถ้าคุณใช้items:

class D:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.items()

>>> d = D(dict(a=1, b=2, c=3))
>>> [v for v in d]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __iter__ returned non-iterator of type 'list'

สิ่งเดียวกันนี้เป็นจริงสำหรับviewitemsซึ่งมีอยู่ใน Python 3

นอกจากนี้เนื่องจากรายการส่งคืนสำเนารายการ(key, value)คู่ของพจนานุกรมจึงมีประสิทธิภาพน้อยลงเว้นแต่คุณต้องการสร้างสำเนาอยู่ดี

ใน Python 2 วิธีที่ดีที่สุดคือใช้iteritemsสำหรับการวนซ้ำ 2to3เครื่องมือที่สามารถแทนที่ด้วยitemsถ้าคุณเคยตัดสินใจที่จะอัพเกรดไปหลาม 3


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.