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基于queue和threading实现多线程下载实例
Oct 08 Python
Python argv用法详解
Jan 08 Python
python中关于for循环的碎碎念
Jun 30 Python
Python实现将Excel转换为json的方法示例
Aug 05 Python
Flask框架Jinjia模板常用语法总结
Jul 19 Python
python安装twisted的问题解析
Aug 21 Python
python如何实现一个刷网页小程序
Nov 27 Python
pyqt5 使用label控件实时显示时间的实例
Jun 14 Python
python实现简单图书管理系统
Nov 22 Python
Pytorch DataLoader 变长数据处理方式
Jan 08 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
Apr 27 Python
python字典的元素访问实例详解
Jul 21 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函数指定默认值方法的小例子
2013/12/04 PHP
PHP实现加密的几种方式介绍
2015/02/22 PHP
php验证手机号码
2015/11/11 PHP
Zend Framework入门之环境配置及第一个Hello World示例(附demo源码下载)
2016/03/21 PHP
Yii数据模型中rules类验证器用法分析
2016/07/15 PHP
php中分页及SqlHelper类用法实例
2017/01/12 PHP
PHP计算近1年的所有月份
2017/03/13 PHP
PHP JWT初识及其简单示例
2018/10/10 PHP
thinkphp框架表单数组实现图片批量上传功能示例
2020/04/04 PHP
仿迅雷焦点广告效果(JQuery版)
2008/11/19 Javascript
JS函数验证总结(方便js客户端输入验证)
2010/10/29 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
js实现div闪烁原理及实现代码
2014/06/24 Javascript
浅谈jQuery hover(over, out)事件函数
2016/12/03 Javascript
js实现一个可以兼容PC端和移动端的div拖动效果实例
2016/12/09 Javascript
使用JavaScript实现表格编辑器(实例讲解)
2017/08/02 Javascript
Angular表格神器ui-grid应用详解
2017/09/29 Javascript
vue.js项目nginx部署教程
2018/04/05 Javascript
Angular使用动态加载组件方法实现Dialog的示例
2018/05/11 Javascript
React学习笔记之高阶组件应用
2018/06/02 Javascript
vue项目部署上线遇到的问题及解决方法
2018/06/10 Javascript
使用Python的Tornado框架实现一个Web端图书展示页面
2016/07/11 Python
python调用系统ffmpeg实现视频截图、http发送
2018/03/06 Python
pandas 两列时间相减换算为秒的方法
2018/04/20 Python
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
2018/12/05 Python
Python中GeoJson和bokeh-1的使用讲解
2019/01/03 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
TensorFlow MNIST手写数据集的实现方法
2020/02/05 Python
Marc O’Polo俄罗斯官方在线商店:德国高端时尚品牌
2019/12/26 全球购物
如何查找和删除数据库中的重复数据
2014/11/05 面试题
应届医学毕业生求职信分享
2013/12/02 职场文书
趣味运动会活动方案
2014/02/12 职场文书
一个都不能少观后感
2015/06/04 职场文书
python tkinter模块的简单使用
2021/04/07 Python