通过Python定义集合数据结构,而不使用库中的set类
在Python中,集合(set)是一种使用频率非常高的数据结构,它是由一组不重复且无序的元素组成的。Python内置了set类,可以方便地创建集合,但是我们也可以通过自己定义类来实现类似的功能。在本文中,我们将通过Python代码构建一个类来实现集合数据结构,并且接口与Python自带的set类相似,包括添加元素、删除元素、判断元素是否在集合中等操作。
实现原理
我们的集合类的实现与现有的set类类似,它主要包含以下几个要素:
- 使用哈希表保存元素;
- 实现添加元素功能;
- 实现删除元素功能;
- 实现判断元素是否在集合中的功能。
在Python中,我们可以使用字典(dict)数据结构来实现哈希表。具体地,我们将集合中的元素作为字典的键,这样就可以快速地判断元素是否在集合中。
代码实现
下面是我们定义的集合类的代码,其中我们使用了Python自带的字典数据类型来存储集合中的元素。
class MySet:
def __init__(self, *args):
self.data = {}
for arg in args:
self.add(arg)
def __repr__(self):
return "MySet({0})".format(list(self))
def __iter__(self):
return iter(self.data.keys())
def __len__(self):
return len(self.data)
def add(self, elem):
self.data[elem] = None
def remove(self, elem):
del self.data[elem]
def discard(self, elem):
if elem in self:
self.remove(elem)
def pop(self):
elem = next(iter(self))
self.remove(elem)
return elem
def clear(self):
self.data.clear()
def __contains__(self, elem):
return elem in self.data
def __le__(self, other):
return all(elem in other for elem in self.data)
def issubset(self, other):
return self <= other
def __lt__(self, other):
return self <= other and self != other
def __ge__(self, other):
return all(elem in self for elem in other)
def issuperset(self, other):
return self >= other
def __gt__(self, other):
return self >= other and self != other
def __or__(self, other):
new_set = MySet()
for elem in self:
new_set.add(elem)
for elem in other:
new_set.add(elem)
return new_set
def union(self, other):
return self | other
def __and__(self, other):
new_set = MySet()
for elem in self:
if elem in other:
new_set.add(elem)
return new_set
def intersection(self, other):
return self & other
def __sub__(self, other):
new_set = MySet()
for elem in self:
if elem not in other:
new_set.add(elem)
return new_set
def difference(self, other):
return self - other
def __xor__(self, other):
new_set = MySet()
for elem in self:
if elem not in other:
new_set.add(elem)
for elem in other:
if elem not in self:
new_set.add(elem)
return new_set
def symmetric_difference(self, other):
return self ^ other
测试代码
为了验证我们定义的集合类是否可以正常工作,我们编写了以下测试代码,在代码中,我们使用自己定义的MySet类来创建集合,并使用其操作方法进行元素的添加、删除、查找等操作。代码输出结果与使用Python自带的set类得到的结果相同,说明我们的自定义类可以与Python内置的set类等效地工作。
import random
def test():
lst = {random.randint(0, 10) for i in range(10)}
a= MySet(*lst)
b = set(lst)
print("lst =", lst)
print("a =", a)
print("b =", b)
print("a == b:", a == b)
# test add
print("a.add(20):", end=" ")
a.add(20)
print("a =", a)
# test remove
elem = random.choice(list(a))
print("a.remove({0}):".format(elem), end=" ")
a.remove(elem)
print("a =", a)
# test discard
elem = random.choice(list(a))
print("a.discard({0}):".format(elem), end=" ")
a.discard(elem)
print("a =", a)
# test pop
print("a.pop():", end=" ")
elem = a.pop()
print(elem, a)
# test clear
print("a.clear():", end=" ")
a.clear()
print(a)
# test __contains__
elem = random.choice(list(b))
print("{0} in a:".format(elem), elem in a)
# test <=
print("a <= b:", a <= b)
# test <
print("a < b:", a < b)
# test >=
print("a >= b:", a >= b)
# test >
print("a > b:", a > b)
# test union
print("a | b:", a | b)
# test intersection
print("a & b:", a & b)
# test difference
print("a - b:", a - b)
# test symmetric_difference
print("a ^ b:", a ^ b)
if __name__ == '__main__':
test()
结论
在本文中,我们通过Python代码的方式自定义了一种集合类来实现了集合数据结构,并且接口与Python自带的set类相似。我们使用哈希表实现了集合中添加、删除元素,查找元素等基本操作,同时在使用Python内置的set类的场景下我们也得到了与set同样的结果。虽然Python自带的set类已经能够满足大多数我们的需求,但我们自定义的集合类为我们提供了一种完全自主控制数据结构实现方式的思路,对于理解底层数据结构的原理有所帮助。
极客笔记