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解析发往本机的数据包示例 (解析数据包)
Jan 16 Python
推荐11个实用Python库
Jan 23 Python
浅谈Python中的可变对象和不可变对象
Jul 07 Python
Python+PIL实现支付宝AR红包
Feb 09 Python
python 用opencv调用训练好的模型进行识别的方法
Dec 07 Python
Python父目录、子目录的相互调用方法
Feb 16 Python
PyQt5 实现给窗口设置背景图片的方法
Jun 13 Python
弄懂这56个Python使用技巧(轻松掌握Python高效开发)
Sep 18 Python
python给指定csv表格中的联系人群发邮件(带附件的邮件)
Dec 31 Python
python实现扫雷游戏
Mar 03 Python
Keras在训练期间可视化训练误差和测试误差实例
Jun 16 Python
基于python制作简易版学生信息管理系统
Apr 20 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
TMDPHP 模板引擎使用教程
2012/03/13 PHP
使用PHP导出Word文档的原理和实例
2013/10/21 PHP
PHP include任意文件或URL介绍
2014/04/29 PHP
WordPress中重置文章循环的rewind_posts()函数讲解
2016/01/11 PHP
js字符编码函数区别分析
2008/06/05 Javascript
js 方法实现返回多个数据的代码
2009/04/30 Javascript
JS 文字符串转换unicode编码函数
2009/05/30 Javascript
javascript 一个函数对同一元素的多个事件响应
2009/07/25 Javascript
40个有创意的jQuery图片、内容滑动及弹出插件收藏集之一
2011/12/31 Javascript
javascript封装的sqlite操作类实例
2015/07/17 Javascript
Bootstrap弹出带合法性检查的登录框实例代码【推荐】
2016/06/23 Javascript
关于JS 预解释的相关理解
2016/06/28 Javascript
jQuery移除或禁用html元素点击事件常用方法小结
2017/02/10 Javascript
深入浅析JavaScript中的RegExp对象
2017/09/18 Javascript
解决bootstrap-select 动态加载数据不显示的问题
2018/08/10 Javascript
node实现生成带参数的小程序二维码并保存到本地功能示例
2018/12/05 Javascript
JS操作json对象key、value的常用方法分析
2019/10/29 Javascript
[01:26]DOTA2荣耀之路2:iG,China
2018/05/24 DOTA
基于python时间处理方法(详解)
2017/08/14 Python
python的unittest测试类代码实例
2017/12/07 Python
Python实现字典按key或者value进行排序操作示例【sorted】
2019/05/03 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
2019/08/13 Python
Python的互斥锁与信号量详解
2019/09/12 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
python GUI库图形界面开发之PyQt5树形结构控件QTreeWidget详细使用方法与实例
2020/03/02 Python
使用Python通过oBIX协议访问Niagara数据的示例
2020/12/04 Python
韩国三星集团旗下时尚品牌官网:SSF SHOP
2016/08/02 全球购物
Myholidays美国:在线旅游网站
2019/08/16 全球购物
Farfetch中文官网:奢侈品牌时尚购物平台
2020/03/15 全球购物
五年级数学教学反思
2014/02/11 职场文书
万能检讨书开头与结尾怎么写
2015/02/17 职场文书
出国留学自荐信模板
2015/03/06 职场文书
单位病假条范文
2015/08/17 职场文书
java Nio使用NioSocket客户端与服务端交互实现方式
2021/06/15 Java/Android
Netty结合Protobuf进行编解码的方法
2021/06/26 Java/Android
mysql配置SSL证书登录的实现
2021/09/04 MySQL