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编写提取日志中的中文的脚本的方法
Apr 30 Python
举例讲解Python中的Null模式与桥接模式编程
Feb 02 Python
Python机器学习logistic回归代码解析
Jan 17 Python
Python随机函数random()使用方法小结
Apr 29 Python
python判断文件是否存在,不存在就创建一个的实例
Feb 18 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
Apr 30 Python
教你一步步利用python实现贪吃蛇游戏
Jun 27 Python
opencv 图像礼帽和图像黑帽的实现
Jul 07 Python
Python自动化操作实现图例绘制
Jul 09 Python
解决Python 写文件报错TypeError的问题
Oct 23 Python
selenium框架中driver.close()和driver.quit()关闭浏览器
Dec 08 Python
python 下载文件的几种方式分享
Apr 07 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
PHP5/ZendEngine2的改进
2006/10/09 PHP
Windows Apache2.2.11及Php5.2.9-1的安装与配置方法
2009/06/08 PHP
php 变量定义方法
2009/06/14 PHP
解析php根据ip查询所在地区(非常有用,赶集网就用到)
2013/07/01 PHP
jquery ui resizable bug解决方法
2010/10/26 Javascript
JS对象与JSON格式数据相互转换
2012/02/20 Javascript
js输出阴历、阳历、年份、月份、周示例代码
2014/01/29 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
2017/05/26 Javascript
用最少的JS代码写出贪吃蛇游戏
2018/01/12 Javascript
vue 使用ref 让父组件调用子组件的方法
2018/02/08 Javascript
JavaScript获取移动设备型号的实现代码(JS获取手机型号和系统)
2018/03/10 Javascript
Vue中使用的EventBus有生命周期
2018/07/12 Javascript
javascript 构建模块化开发过程解析
2019/09/11 Javascript
vue实现鼠标移过出现下拉二级菜单功能
2019/12/12 Javascript
python 图片验证码代码
2008/12/07 Python
Python标准库之循环器(itertools)介绍
2014/11/25 Python
python中list列表的高级函数
2016/05/17 Python
你眼中的Python大牛 应该都有这份书单
2017/10/31 Python
Python实现PS图像调整之对比度调整功能示例
2018/01/26 Python
Python实现ping指定IP的示例
2018/06/04 Python
为什么str(float)在Python 3中比Python 2返回更多的数字
2018/10/16 Python
python bmp转换为jpg 并删除原图的方法
2018/10/25 Python
使用pandas实现csv/excel sheet互相转换的方法
2018/12/10 Python
Python中itertools的用法详解
2020/02/07 Python
python数据预处理方式 :数据降维
2020/02/24 Python
利用Python中的Xpath实现一个在线汇率转换器
2020/09/09 Python
opencv python 对指针仪表读数识别的两种方式
2021/01/14 Python
购买澳大利亚最好的服装和内衣在线:BONDS
2016/10/14 全球购物
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
英国时尚高尔夫服装购物网站:Trendy Golf
2020/01/10 全球购物
自强之星事迹材料
2014/05/12 职场文书
儿子满月酒致辞
2015/07/29 职场文书
就业指导讲座心得体会
2016/01/15 职场文书
nginx配置ssl实现https的方法示例
2021/03/31 Servers
教你怎么用python爬取爱奇艺热门电影
2021/05/20 Python
Python实现简单的俄罗斯方块游戏
2021/09/25 Python