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 相关文章推荐
在GitHub Pages上使用Pelican搭建博客的教程
Apr 25 Python
深入解析Python中的集合类型操作符
Aug 19 Python
Python中的模块导入和读取键盘输入的方法
Oct 16 Python
Python实例一个类背后发生了什么
Feb 09 Python
Python:Scrapy框架中Item Pipeline组件使用详解
Dec 27 Python
python爬虫使用cookie登录详解
Dec 27 Python
python docx 中文字体设置的操作方法
May 08 Python
python保留小数位的三种实现方法
Jan 07 Python
Python语言异常处理测试过程解析
Jan 08 Python
python global和nonlocal用法解析
Feb 03 Python
详解python程序中的多任务
Sep 16 Python
python海龟绘图之画国旗实例代码
Nov 11 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
6个超实用的PHP代码片段
2015/08/10 PHP
PHP中对数组的一些常用的增、删、插操作函数总结
2015/11/27 PHP
PhpStorm terminal无法输入命令的解决方法
2016/10/09 PHP
我也种棵OO树JXTree[js+css+xml]
2007/04/02 Javascript
JS面向对象、prototype、call()、apply()
2009/05/14 Javascript
IE6不能修改NAME问题的解决方法
2010/09/03 Javascript
javascript 运算数的求值顺序
2011/08/23 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
2014/02/26 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
一款基于jQuery的图片场景标注提示弹窗特效
2015/01/05 Javascript
JS根据key值获取URL中的参数值及把URL的参数转换成json对象
2015/08/26 Javascript
Node.js与Sails ~项目结构与Mvc实现及日志机制
2015/10/14 Javascript
JavaScript实现简洁的俄罗斯方块完整实例
2016/03/01 Javascript
浅谈JS原型对象和原型链
2016/03/02 Javascript
JavaScript的模块化开发框架Sea.js上手指南
2016/05/12 Javascript
学习Node.js模块机制
2016/10/17 Javascript
Vue2 配置 Axios api 接口调用文件的方法
2017/11/13 Javascript
vue基础知识--axios合并请求和slot
2020/06/04 Javascript
解决Vue @submit 提交后不刷新页面问题
2020/07/18 Javascript
[49:21]TNC vs VG 2019DOTA2国际邀请赛淘汰赛 胜者组赛BO3 第三场 8.20.mp4
2019/08/22 DOTA
使用Python脚本将文字转换为图片的实例分享
2015/08/29 Python
高效测试用例组织算法pairwise之Python实现方法
2017/07/19 Python
numpy求平均值的维度设定的例子
2019/08/24 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
2020/02/07 Python
Python趣味入门教程之循环语句while
2020/08/26 Python
前端隐藏出边界内容的实现方法
2016/04/14 HTML / CSS
HTML5 Canvas实现玫瑰曲线和心形图案的代码实例
2014/04/10 HTML / CSS
加拿大约会网站:EliteSingles.ca
2018/01/12 全球购物
Mountain Hardwear官网:攀岩服装和户外装备
2019/09/26 全球购物
日本最大的购物网站乐天市场国际版:Rakuten Global Market(支持中文)
2020/02/03 全球购物
高中生家长寄语大全
2014/04/03 职场文书
党员创先争优心得体会
2014/09/11 职场文书
家长给老师的感谢信
2015/01/20 职场文书
惹女朋友生气检讨书
2015/05/06 职场文书
行为习惯主题班会
2015/08/14 职场文书
详细介绍Java中的CyclicBarrier
2022/04/13 Java/Android