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 相关文章推荐
python实现sublime3的less编译插件示例
Apr 27 Python
python处理PHP数组文本文件实例
Sep 18 Python
python读取oracle函数返回值
Jul 18 Python
python使用xlrd与xlwt对excel的读写和格式设定
Jan 21 Python
pyenv命令管理多个Python版本
Mar 26 Python
Python数据结构之图的应用示例
May 11 Python
使用CodeMirror实现Python3在线编辑器的示例代码
Jan 14 Python
python+pyqt5实现24点小游戏
Jan 24 Python
Python英文文本分词(无空格)模块wordninja的使用实例
Feb 20 Python
Python实现使用request模块下载图片demo示例
May 24 Python
python+opencv实现移动侦测(帧差法)
Mar 20 Python
python中tkinter窗口位置\坐标\大小等实现示例
Jul 09 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
Yii调试SQL的常用方法
2014/07/09 PHP
php遍历目录下文件并按修改时间排序操作示例
2019/07/12 PHP
Laravel5.1框架路由分组用法实例分析
2020/01/04 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
javascript在事件监听方面的兼容性小结
2010/04/07 Javascript
基于jquery实现控制经纬度显示地图与卫星
2013/05/20 Javascript
不使用浏览器运行javascript代码的方法
2013/07/24 Javascript
一个css与js结合的下拉菜单支持主流浏览器
2014/10/08 Javascript
NodeJS学习笔记之MongoDB模块
2015/01/13 NodeJs
详解javascript实现瀑布流绝对式布局
2016/01/29 Javascript
json对象与数组以及转换成js对象的简单实现方法
2016/06/24 Javascript
jquery实现ajax提交表单信息的简单方法(推荐)
2016/08/24 Javascript
angularjs指令之绑定策略(@、=、&)
2017/04/13 Javascript
JavaScript实现短信倒计时60s
2017/10/09 Javascript
关于 angularJS的一些用法
2017/11/29 Javascript
Nginx 配置多站点vhost 的方法
2018/01/07 Javascript
vue-cli3.0配置及使用注意事项详解
2018/09/05 Javascript
js中数组对象去重的两种方法
2019/01/18 Javascript
vue-cli3+typescript新建一个项目的思路分析
2019/08/06 Javascript
对vuex中getters计算过滤操作详解
2019/11/06 Javascript
javascript单张多张图无缝滚动实例代码
2020/05/10 Javascript
vue tab切换,解决echartst图表宽度只有100px的问题
2020/07/19 Javascript
深入了解Vue.js 混入(mixins)
2020/07/23 Javascript
Python中文竖排显示的方法
2015/07/28 Python
Django中如何使用sass的方法步骤
2019/07/09 Python
django创建最简单HTML页面跳转方法
2019/08/16 Python
python3下pygame如何实现显示中文
2020/01/11 Python
使用python脚本自动生成K8S-YAML的方法示例
2020/07/12 Python
Python如何读写字节数据
2020/08/05 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
2020/11/30 Python
Python如何实现单例模式
2016/06/03 面试题
会计岗位职责模板
2014/03/12 职场文书
社团活动总结模板
2014/06/30 职场文书
鲁冰花观后感
2015/06/10 职场文书
医院见习总结
2015/06/24 职场文书
SpringBoot+VUE实现数据表格的实战
2021/08/02 Java/Android