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写入CSV文件的方法
Jul 08 Python
python判断字符串是否是json格式方法分享
Nov 07 Python
python微信跳一跳游戏辅助代码解析
Jan 29 Python
python opencv之分水岭算法示例
Feb 24 Python
Python对数据进行插值和下采样的方法
Jul 03 Python
Python面向对象之类的定义与继承用法示例
Jan 14 Python
PyQt5固定窗口大小的方法
Jun 18 Python
Python绘制二维曲线的日常应用详解
Dec 04 Python
wxpython自定义下拉列表框过程图解
Feb 14 Python
Python 调用 ES、Solr、Phoenix的示例代码
Nov 23 Python
Python控制鼠标键盘代码实例
Dec 08 Python
Python中的pprint模块
Nov 27 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中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
2012/09/07 PHP
PHP编码规范的深入探讨
2013/06/06 PHP
PHP开发微信支付的代码分享
2014/05/25 PHP
yii2控制器Controller Ajax操作示例
2016/07/23 PHP
PHP简单检测网址是否能够正常打开的方法
2016/09/04 PHP
PHP实现根据数组的值进行分组的方法
2017/04/20 PHP
PHP使用preg_split和explode分割textarea存放内容的方法分析
2017/07/03 PHP
php实现文章评论系统
2019/02/18 PHP
PHP字符串和十六进制如何实现互相转换
2020/07/16 PHP
JS JavaScript获取Url参数,src属性参数
2021/03/09 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
jquery实现非叠加式的搜索框提示效果
2014/01/07 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
2014/05/19 Javascript
javascript数组去重的方法汇总
2015/04/14 Javascript
Node.js+Express配置入门教程
2016/05/19 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
jQuery事件与动画基础详解
2017/02/23 Javascript
详解vue 配合vue-resource调用接口获取数据
2017/06/22 Javascript
jQuery length 和 size()区别总结
2018/04/26 jQuery
JavaScript实现美化滑块效果
2019/05/17 Javascript
Vue项目中ESlint规范示例代码
2019/07/04 Javascript
[01:46]辉夜杯—打造中国DOTA新格局
2015/12/25 DOTA
python实现指定字符串补全空格的方法
2015/04/30 Python
python OpenCV学习笔记之绘制直方图的方法
2018/02/08 Python
python如何让类支持比较运算
2018/03/20 Python
基于Python pip用国内镜像下载的方法
2018/06/12 Python
解决pytorch 模型复制的一些问题
2021/03/03 Python
美国首屈一指的高品质珠宝设计师和零售商:Allurez
2018/01/23 全球购物
美国婚礼礼品网站:MyWeddingFavors
2018/09/26 全球购物
大学生职业生涯规划书
2014/03/14 职场文书
保护环境倡议书范文
2014/05/13 职场文书
2014年信贷员工作总结
2014/11/18 职场文书
管理人员岗位职责
2015/02/14 职场文书
社区艾滋病宣传活动总结
2015/05/07 职场文书
先进教师个人主要事迹材料
2015/11/03 职场文书
JavaScript 中for/of,for/in 的详细介绍
2021/11/17 Javascript