Python 实现集合Set的示例


Posted in Python onDecember 21, 2020

Python的集合set原理

集合(set)是一个无序的不重复元素序列。

可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

class Array(object):

 def __init__(self, size=32, init=None):
  self._size = size
  self._items = [init] * self._size

 def __getitem__(self, index):
  return self._items[index]

 def __setitem__(self, index, value):
  self._items[index] = value

 def __len__(self):
  return self._size

 def clear(self, value=None):
  for i in range(len(self._items)):
   self._items[i] = value

 def __iter__(self):
  for item in self._items:
   yield item

class Slot(object):
 """定义一个 hash 表 数组的槽
 注意,一个槽有三种状态,看你能否想明白
 1.从未使用 HashMap.UNUSED。此槽没有被使用和冲突过,查找时只要找到 UNUSED 就不用再继续探查了
 2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素扔可能是有key
 3.槽正在使用 Slot 节点
 """
 def __init__(self, key, value):
  self.key, self.value = key, value

class HashTable(object):
 # 表示从未被使用过
 UNUSED = None
 # 使用过,但是被删除了
 EMPTY = Slot(None, None)

 def __init__(self):
  self._table = Array(8, init=HashTable.UNUSED)
  self.length = 0

 # 负载因子
 @property
 def _load_factor(self):
  return self.length/float(len(self._table))

 def __len__(self):
  return self.length

 # 哈希函数 用内置的哈希哈数进行哈希一下,然后对数组长度取模
 def _hash(self, key):
  return abs(hash(key)) % len(self._table)

 def _find_key(self, key):
  # 得到第一个值的位置
  index = self._hash(key)
  _len = len(self._table)
  # 当这个槽不是未使用过的,才接着往下找;如果是未使用过的,这个key肯定不存在
  while self._table[index] is not HashTable.UNUSED:
   # 槽使用过,但是被删除了
   if self._table[index] is HashTable.EMPTY:
    # cpython解决哈希冲突的一种方式
    index = (index*5 + 1) % _len
    continue
   elif self._table[index] == key:
    return index
   else:
    index = (index * 5 + 1) % _len
  return None

 # 检测槽是否能被插入
 def _slot_can_insert(self, index):
  return (self._table[index] is HashTable.EMPTY or self._table[index] is HashTable.UNUSED)

 # 找到能被插入的槽的index
 def _find_slot_insert(self, key):
  # 得到第一个值的位置
  index = self._hash(key)
  _len = len(self._table)
  while not self._slot_can_insert(index):
   index = (index * 5 + 1) % _len
  return index

 # in 操作符
 def __contains__(self, key):
  index = self._find_key(key)
  return index is not None

 def add(self, key, value):
  if key in self:
   index = self._find_key(key)
   # 更新值
   self._table[index].value = value
   return False
  else:
   index = self._find_slot_insert(key)
   self._table[index] = Slot(key, value)
   self.length += 1
   if self._load_factor > 0.8:
    return self._rehash()
   return True

 def _rehash(self):
  oldtable = self._table
  newsize = len(self._table) * 2
  # 新的table
  self._table = Array(newsize, HashTable.UNUSED)
  self.length = 0
  for slot in oldtable:
   if slot is not HashTable.UNUSED and slot is not HashTable.EMPTY:
    index = self._find_slot_insert(slot.key)
    self._table[index] = slot
    self.length += 1

 def get(self, key, default=None):
  index = self._find_key(key)
  if index is None:
   return default
  else:
   return self._table[index].value

 def remove(self, key):
  index = self._find_key(key)
  if index is None:
   raise KeyError
  value = self._table[index].value
  self.length -= 1
  # 把槽设置为空槽
  self._table[index] = HashTable.EMPTY
  return value

 def __iter__(self):
  for slot in self._table:
   if slot not in (HashTable.UNUSED, HashTable.EMPTY):
    yield slot.value


class SetADT(HashTable):

 def add(self, key):
  return super(SetADT, self).add(key, True)

 def __and__(self, other_set):
  # 求交集
  new_set = SetADT()
  for element_a in self:
   if element_a in other_set:
    new_set.add(element_a)
  return new_set

 def __sub__(self, other_set):
  # 求差集
  new_set = SetADT()
  for element_a in self:
   if element_a not in other_set:
    new_set.add(element_a)
  return new_set

 def __or__(self, other_set):
  # 求交集
  new_set = SetADT()
  for element_a in self:
   new_set.add(element_a)
  for element_b in other_set:
   new_set.add(element_b)
  return new_set

以上就是Python 实现集合Set的示例的详细内容,更多关于Python 实现集合Set的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
使用Django的模版来配合字符串翻译工作
Jul 27 Python
Python打包可执行文件的方法详解
Sep 19 Python
代码讲解Python对Windows服务进行监控
Feb 11 Python
Python3中正则模块re.compile、re.match及re.search函数用法详解
Jun 11 Python
对python GUI实现完美进度条的示例详解
Dec 13 Python
Python 调用PIL库失败的解决方法
Jan 08 Python
在PyCharm下使用 ipython 交互式编程的方法
Jan 17 Python
python下载库的步骤方法
Oct 12 Python
Python解析json代码实例解析
Nov 25 Python
Python list运算操作代码实例解析
Jan 20 Python
python代码实现TSNE降维数据可视化教程
Feb 28 Python
详解Python高阶函数
Aug 15 Python
Python 实现二叉查找树的示例代码
Dec 21 #Python
如何利用Python matplotlib绘制雷达图
Dec 21 #Python
OpenCV+python实现膨胀和腐蚀的示例
Dec 21 #Python
python opencv肤色检测的实现示例
Dec 21 #Python
OpenCV+Python3.5 简易手势识别的实现
Dec 21 #Python
如何使用python-opencv批量生成带噪点噪线的数字验证码
Dec 21 #Python
python 录制系统声音的示例
Dec 21 #Python
You might like
PHP多文件上传实例
2015/07/09 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
php用wangeditor3实现图片上传功能
2019/08/22 PHP
javascript innerHTML使用分析
2010/12/03 Javascript
基于JQuery的动态删除Table表格的行和列的代码
2011/05/12 Javascript
jquery实现盒子下拉效果示例代码
2013/09/12 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
jQuery中trigger()方法用法实例
2015/01/19 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
2016/01/04 Javascript
详解AngularJS 模态对话框
2016/04/07 Javascript
AngularJS入门教程之控制器详解
2016/07/27 Javascript
微信公众号支付H5调用支付解析
2016/11/04 Javascript
js的OOP继承实现(必看篇)
2017/02/18 Javascript
AngularJS表单提交实例详解
2017/02/18 Javascript
详解JS中遍历语法的比较
2017/04/07 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
使用vue完成微信公众号网页小记(推荐)
2019/04/28 Javascript
通过微信公众平台获取公众号文章的方法示例
2019/12/25 Javascript
JS实现网站吸顶条
2020/01/08 Javascript
WebStorm无法正确识别Vue3组合式API的解决方案
2021/02/18 Vue.js
使用Python对Excel进行读写操作
2017/03/30 Python
python计算日期之间的放假日期
2018/06/05 Python
使用Python微信库itchat获得好友和群组已撤回的消息
2018/06/24 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
django中的图片验证码功能
2019/09/18 Python
Python ini文件常用操作方法解析
2020/04/26 Python
Java语言的优势
2015/01/10 面试题
学校文明单位申报材料
2014/05/06 职场文书
保护环境倡议书500字
2014/05/19 职场文书
销售简历自我评价怎么写
2014/09/26 职场文书
2015年社区妇联工作总结
2015/04/21 职场文书
办公室主任岗位竞聘书
2015/09/15 职场文书
python实现三阶魔方还原的示例代码
2021/04/28 Python
Echarts如何重新渲染实例详解
2022/05/30 Javascript
类和原型的设计模式之复制与委托差异
2022/07/07 Javascript