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 相关文章推荐
PyTorch上搭建简单神经网络实现回归和分类的示例
Apr 28 Python
用Python将结果保存为xlsx的方法
Jan 28 Python
深入理解Django-Signals信号量
Feb 19 Python
分析运行中的 Python 进程详细解析
Jun 22 Python
Python中的正则表达式与JSON数据交换格式
Jul 03 Python
python调用其他文件函数或类的示例
Jul 16 Python
django表单的Widgets使用详解
Jul 22 Python
Python配置文件处理的方法教程
Aug 29 Python
TensorFlow中如何确定张量的形状实例
Jun 23 Python
Python 如何测试文件是否存在
Jul 31 Python
关于Python3的import问题(pycharm可以运行命令行import错误)
Nov 18 Python
Python爬虫实战案例之爬取喜马拉雅音频数据详解
Dec 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
php 目录遍历、删除 函数的使用介绍
2013/04/28 PHP
php读取txt文件并将数据插入到数据库
2016/02/23 PHP
Laravel框架创建路由的方法详解
2019/09/04 PHP
html中table数据排序的js代码
2011/08/09 Javascript
JavaScript去除空格的三种方法(正则/传参函数/trim)
2013/02/06 Javascript
轻松创建nodejs服务器(2):nodejs服务器的构成分析
2014/12/18 NodeJs
jQuery EasyUI window窗口使用实例代码
2017/12/25 jQuery
vue+iview+less 实现换肤功能
2018/08/17 Javascript
Vue绑定内联样式问题
2018/10/17 Javascript
微信小程序网络层封装的实现(promise, 登录锁)
2019/05/08 Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
2019/08/12 Javascript
Vue Object 的变化侦测实现代码
2020/04/15 Javascript
在Python中使用poplib模块收取邮件的教程
2015/04/29 Python
Python 常用的安装Module方式汇总
2017/05/06 Python
Linux下python制作名片示例
2018/07/20 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
2019/07/23 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
Pytorch中的variable, tensor与numpy相互转化的方法
2019/10/10 Python
python 插入日期数据到Oracle实例
2020/03/02 Python
Python flask框架如何显示图像到web页面
2020/06/03 Python
Python 实现3种回归模型(Linear Regression,Lasso,Ridge)的示例
2020/10/15 Python
python 利用百度API识别图片文字(多线程版)
2020/12/14 Python
python用700行代码实现http客户端
2021/01/14 Python
基于HTML5+tracking.js实现刷脸支付功能
2020/04/16 HTML / CSS
英国儿童图书网站:Scholastic
2017/03/26 全球购物
美国在线奢侈品寄售商店:Luxury Garage Sale
2018/08/19 全球购物
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
如何用Lucene索引数据库
2016/02/23 面试题
营销总经理的岗位职责
2013/12/15 职场文书
关于迟到的检讨书
2014/01/26 职场文书
商铺租赁意向书
2014/04/01 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
数学考试作弊检讨书300字
2015/02/16 职场文书
立项申请报告范本
2015/05/15 职场文书
2016中秋节月饼促销广告语
2016/01/28 职场文书
阿里云服务器部署mongodb的详细过程
2021/09/04 MongoDB