Python มีพจนานุกรมที่เรียงลำดับแล้ว สิ่งที่เกี่ยวกับชุดสั่ง?
collections.Counter
คือกระเป๋าของ Python
Python มีพจนานุกรมที่เรียงลำดับแล้ว สิ่งที่เกี่ยวกับชุดสั่ง?
collections.Counter
คือกระเป๋าของ Python
คำตอบ:
มีเป็นชุดที่สั่งซื้อ (เป็นไปได้เชื่อมโยงใหม่ ) สูตรสำหรับที่จะเรียกจากงูหลาม 2 เอกสาร สิ่งนี้รันบน Py2.6 หรือใหม่กว่าและ 3.0 หรือใหม่กว่าโดยไม่มีการดัดแปลงใด ๆ อินเทอร์เฟซเกือบจะเหมือนกับชุดปกติยกเว้นว่าการเริ่มต้นควรทำกับรายการ
OrderedSet([1, 2, 3])
นี่คือ MutableSet ดังนั้นลายเซ็นสำหรับ.union
ไม่ตรงกับชุด แต่เนื่องจากมี__or__
สิ่งที่คล้ายกันสามารถเพิ่มได้อย่างง่ายดาย:
@staticmethod
def union(*sets):
union = OrderedSet()
union.union(*sets)
return union
def union(self, *sets):
for set in sets:
self |= set
update
, ,union
intersection
union
ในชั้นเรียนเดียวกัน คนสุดท้ายจะ "ชนะ" และคนแรกจะล้มเหลวที่จะอยู่ที่รันไทม์ นี่เป็นเพราะOrderedSet.union
(ไม่มีการ parens) ต้องอ้างถึงวัตถุเดี่ยว
กุญแจของพจนานุกรมนั้นไม่เหมือนใคร ดังนั้นหากใครไม่สนใจค่าในพจนานุกรมสั่ง (เช่นโดยการกำหนดพวกเขาNone
) แล้วหนึ่งมีชุดสั่งซื้อเป็นหลัก
ในฐานะของงูหลาม 3.1collections.OrderedDict
มี ต่อไปนี้เป็นตัวอย่างการใช้งานของ OrderedSet (โปรดทราบว่าจำเป็นต้องกำหนดหรือลบล้างวิธีการเพียงไม่กี่วิธีcollections.OrderedDict
และcollections.MutableSet
ทำการยกของหนัก)
import collections
class OrderedSet(collections.OrderedDict, collections.MutableSet):
def update(self, *args, **kwargs):
if kwargs:
raise TypeError("update() takes no keyword arguments")
for s in args:
for e in s:
self.add(e)
def add(self, elem):
self[elem] = None
def discard(self, elem):
self.pop(elem, None)
def __le__(self, other):
return all(e in other for e in self)
def __lt__(self, other):
return self <= other and self != other
def __ge__(self, other):
return all(e in self for e in other)
def __gt__(self, other):
return self >= other and self != other
def __repr__(self):
return 'OrderedSet([%s])' % (', '.join(map(repr, self.keys())))
def __str__(self):
return '{%s}' % (', '.join(map(repr, self.keys())))
difference = __sub__
difference_update = __isub__
intersection = __and__
intersection_update = __iand__
issubset = __le__
issuperset = __ge__
symmetric_difference = __xor__
symmetric_difference_update = __ixor__
union = __or__
OrderedSet
ซึ่ง subclasses OrderedDict
และabc.Set
แล้วกำหนด__len__
, และ__iter__
__contains__
collections
แต่อย่างอื่นคำแนะนำที่ดี
OrderedSet([1,2,3])
เพิ่ม TypeError คอนสตรัคทำงานอย่างไร? ไม่มีตัวอย่างการใช้งาน
คำตอบคือไม่ แต่คุณสามารถใช้collections.OrderedDict
จากไลบรารีมาตรฐาน Python ด้วยปุ่มเพียง (และค่าเป็นNone
) เพื่อจุดประสงค์เดียวกัน
ปรับปรุง : ณ หลาม 3.7 (และ CPython 3.6) มาตรฐานdict
มีการรับประกันว่าจะรักษาลำดับและเป็น performant OrderedDict
มากกว่า (สำหรับความเข้ากันได้แบบย้อนกลับและโดยเฉพาะการอ่านอย่างไรก็ตามคุณอาจต้องการใช้งานต่อOrderedDict
ไป)
นี่คือตัวอย่างของวิธีการใช้dict
เป็นชุดสั่งซื้อเพื่อกรองรายการที่ซ้ำกันในขณะที่รักษาลำดับดังนั้นการเลียนแบบชุดสั่งซื้อ ใช้dict
วิธีการเรียนfromkeys()
เพื่อสร้าง dict จากนั้นเพียงแค่ถามkeys()
กลับ
>>> keywords = ['foo', 'bar', 'bar', 'foo', 'baz', 'foo']
>>> list(dict.fromkeys(keywords))
['foo', 'bar', 'baz']
dict.fromkeys()
กับวานิลลา แต่ในกรณีนั้นคำสั่งซื้อที่สำคัญจะได้รับการเก็บรักษาไว้ในการใช้งาน CPython 3.6+ เท่านั้นดังนั้นจึงOrderedDict
เป็นโซลูชันที่พกพาได้มากขึ้นเมื่อมีคำสั่ง
keys = (1,2,3,1,2,1)
list(OrderedDict.fromkeys(keys).keys())
-> [1, 2, 3]
, python-3.7 มันได้ผล.
dict
, set
ในหลาม 3.7+ น่าเสียดายที่ไม่ได้รักษาลำดับ
ฉันสามารถทำได้หนึ่งที่ดีกว่า OrderedSet: boltons มีpure-Python, IndexedSet
ชนิดที่เข้ากันได้กับ 2/3 ซึ่งไม่เพียง แต่ชุดที่ได้รับคำสั่งเท่านั้น แต่ยังรองรับการจัดทำดัชนี (เช่นเดียวกับรายการ)
เพียงpip install boltons
(หรือคัดลอกsetutils.py
ไปยัง codebase ของคุณ) นำเข้าIndexedSet
และ:
>>> from boltons.setutils import IndexedSet
>>> x = IndexedSet(list(range(4)) + list(range(8)))
>>> x
IndexedSet([0, 1, 2, 3, 4, 5, 6, 7])
>>> x - set(range(2))
IndexedSet([2, 3, 4, 5, 6, 7])
>>> x[-1]
7
>>> fcr = IndexedSet('freecreditreport.com')
>>> ''.join(fcr[:fcr.index('.')])
'frecditpo'
ทุกอย่างไม่เหมือนใครและคงความเป็นระเบียบเรียบร้อย การเปิดเผยข้อมูลเต็มรูปแบบ: ผมเขียนIndexedSet
แต่ยังหมายถึงการที่คุณสามารถข้อผิดพลาดฉันถ้ามีปัญหาใด ๆ :)
ในขณะที่คนอื่น ๆ ชี้ให้เห็นว่าไม่มีการติดตั้งชุดการเรียงลำดับการแทรกไว้ใน Python ในตัว (แต่) ฉันรู้สึกว่าคำถามนี้ไม่มีคำตอบที่ระบุว่ามีอะไรในPyPI PyPI
มีแพ็คเกจ:
การนำไปใช้งานบางส่วนจะขึ้นอยู่กับสูตรที่โพสต์โดย Raymond Hettinger ไปยัง ActiveStateซึ่งจะกล่าวถึงในคำตอบอื่น ๆ ที่นี่ด้วย
my_set[5]
)remove(item)
การใช้งานทั้งสองมี O (1) สำหรับadd(item)
และ__contains__(item)
( item in my_set
)
set.union
ไม่สามารถใช้งานได้แม้ว่าจะสืบทอดcollections.abc.Set
มา
หากคุณกำลังใช้ชุดที่สั่งซื้อเพื่อรักษาลำดับการเรียงให้ลองใช้ชุดการเรียงที่เรียงลำดับจาก PyPI sortedcontainersโมดูลให้SortedSetเพียงเพื่อการนี้ ประโยชน์บางประการ: pure-Python, การใช้งานที่รวดเร็ว -C, การครอบคลุมการทดสอบ 100%, ชั่วโมงการทดสอบความเครียด
การติดตั้งจาก PyPI ทำได้ง่ายด้วย pip:
pip install sortedcontainers
โปรดทราบว่าหากคุณไม่สามารถ pip install
เพียงแค่ดึงไฟล์ sortedlist.py และ sortedset.py จากพื้นที่เก็บข้อมูลโอเพนซอร์ส
เมื่อติดตั้งแล้วคุณสามารถ:
from sortedcontainers import SortedSet
help(SortedSet)
โมดูลที่จัดเรียงยังรักษา เปรียบเทียบประสิทธิภาพกับการนำไปใช้ทางเลือกต่าง ๆ
สำหรับความคิดเห็นที่ถามเกี่ยวกับประเภทของกระเป๋า Python มีอีกทางเลือกหนึ่งคือประเภทข้อมูลSortedListซึ่งสามารถใช้ในการใช้ถุงอย่างมีประสิทธิภาพ
SortedSet
ชั้นเรียนมีสมาชิกที่จะต้องเปรียบเทียบและ hashable
set
และfrozenset
ยังต้องมีองค์ประกอบที่จะแฮช ข้อ จำกัด ที่เปรียบเทียบได้คือส่วนเพิ่มเติมสำหรับSortedSet
แต่ก็เป็นข้อ จำกัด ที่ชัดเจนเช่นกัน
ในกรณีที่คุณใช้หมีแพนด้าในรหัสของคุณแล้วIndex
วัตถุนั้นจะทำงานเหมือนชุดสั่งซื้อดังที่แสดงในบทความนี้บทความนี้
ตัวอย่างจากบทความ:
indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])
indA & indB # intersection
indA | indB # union
indA - indB # difference
indA ^ indB # symmetric difference
indA.difference(indB)
เครื่องหมายลบทำการลบมาตรฐาน
ช้าไปนิดหน่อยกับเกม แต่ฉันเขียนชั้นเรียนsetlist
ซึ่งเป็นส่วนหนึ่งของcollections-extended
การดำเนินการทั้งสองอย่างSequence
และSet
>>> from collections_extended import setlist
>>> sl = setlist('abracadabra')
>>> sl
setlist(('a', 'b', 'r', 'c', 'd'))
>>> sl[3]
'c'
>>> sl[-1]
'd'
>>> 'r' in sl # testing for inclusion is fast
True
>>> sl.index('d') # so is finding the index of an element
4
>>> sl.insert(1, 'd') # inserting an element already in raises a ValueError
ValueError
>>> sl.index('d')
4
GitHub: https://github.com/mlenzen/collections-extended
เอกสารประกอบ: http://collections-extended.lenzm.net/en/latest/
ไม่มีOrderedSet
ในห้องสมุดอย่างเป็นทางการ ฉันทำ cheatsheet ครบถ้วนสมบูรณ์ของโครงสร้างข้อมูลทั้งหมดสำหรับการอ้างอิงของคุณ
DataStructure = {
'Collections': {
'Map': [
('dict', 'OrderDict', 'defaultdict'),
('chainmap', 'types.MappingProxyType')
],
'Set': [('set', 'frozenset'), {'multiset': 'collection.Counter'}]
},
'Sequence': {
'Basic': ['list', 'tuple', 'iterator']
},
'Algorithm': {
'Priority': ['heapq', 'queue.PriorityQueue'],
'Queue': ['queue.Queue', 'multiprocessing.Queue'],
'Stack': ['collection.deque', 'queue.LifeQueue']
},
'text_sequence': ['str', 'byte', 'bytearray']
}
ParallelRegressionแพคเกจให้ลิสท์ ()สั่งซื้อชุดชั้นที่มีมากขึ้นวิธีสมบูรณ์กว่าตัวเลือกขึ้นอยู่กับสูตร ActiveState สนับสนุนวิธีการทั้งหมดที่มีอยู่สำหรับรายการและส่วนใหญ่ถ้าไม่ใช่วิธีทั้งหมดที่มีให้สำหรับชุด
เช่นเดียวกับคำตอบอื่น ๆ ที่กล่าวถึงเช่นเดียวกับ python 3.7+ dict นั้นเรียงตามคำจำกัดความ แทนที่จะเป็นคลาสย่อยOrderedDict
เราสามารถใช้คลาสย่อยabc.collections.MutableSet
หรือtyping.MutableSet
ใช้คีย์ของ dict เพื่อเก็บค่าของเรา
class OrderedSet(typing.MutableSet[T]):
"""A set that preserves insertion order by internally using a dict."""
def __init__(self, iterable: t.Iterator[T]):
self._d = dict.fromkeys(iterable)
def add(self, x: T) -> None:
self._d[x] = None
def discard(self, x: T) -> None:
self._d.pop(x)
def __contains__(self, x: object) -> bool:
return self._d.__contains__(x)
def __len__(self) -> int:
return self._d.__len__()
def __iter__(self) -> t.Iterator[T]:
return self._d.__iter__()
จากนั้นเพียง:
x = OrderedSet([1, 2, -1, "bar"])
x.add(0)
assert list(x) == [1, 2, -1, "bar", 0]
ฉันใส่รหัสนี้ในห้องสมุดขนาดเล็กเพื่อให้ทุกคนสามารถเพียงแค่pip install
มัน
สำหรับวัตถุประสงค์มากมายเพียงแค่เรียกเรียงจะพอเพียง ตัวอย่างเช่น
>>> s = set([0, 1, 2, 99, 4, 40, 3, 20, 24, 100, 60])
>>> sorted(s)
[0, 1, 2, 3, 4, 20, 24, 40, 60, 99, 100]
หากคุณกำลังจะใช้สิ่งนี้ซ้ำ ๆ จะมีค่าใช้จ่ายเกิดขึ้นโดยการเรียกฟังก์ชันเรียงลำดับดังนั้นคุณอาจต้องการบันทึกรายการผลลัพธ์ตราบใดที่คุณเปลี่ยนชุดเสร็จแล้ว หากคุณต้องการรักษาองค์ประกอบที่ไม่ซ้ำกันและเรียงลำดับฉันเห็นด้วยกับข้อเสนอแนะของการใช้ OrderedDict จากคอลเลกชันที่มีค่าโดยพลการเช่นไม่มี
ดังนั้นฉันยังมีรายการเล็ก ๆ ที่ฉันมีความเป็นไปได้ที่จะแนะนำค่าที่ไม่ซ้ำกันอย่างชัดเจน
ฉันค้นหาการมีอยู่ของรายการเฉพาะบางประเภท แต่แล้วก็รู้ว่าการทดสอบการมีอยู่ขององค์ประกอบก่อนที่จะเพิ่มการทำงานได้ดี
if(not new_element in my_list):
my_list.append(new_element)
ฉันไม่ทราบว่ามีคำเตือนวิธีง่าย ๆ นี้หรือไม่ แต่ก็แก้ปัญหาของฉันได้