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网络爬虫采集联想词示例
Feb 11 Python
使用Python对Excel进行读写操作
Mar 30 Python
Python3.x对JSON的一些操作示例
Sep 01 Python
python机器人行走步数问题的解决
Jan 29 Python
python 实现A*算法的示例代码
Aug 13 Python
详解Python 爬取13个旅游城市,告诉你五一大家最爱去哪玩?
May 07 Python
python3 pathlib库Path类方法总结
Dec 26 Python
python实现随机加减法生成器
Feb 24 Python
Python+OpenCV图像处理——图像二值化的实现
Oct 24 Python
GitHub上值得推荐的8个python 项目
Oct 30 Python
Python 实现RSA加解密文本文件
Dec 30 Python
python实现图片九宫格分割的示例
Apr 25 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
上海无线电三厂简史修改版
2021/03/01 无线电
浅析is_writable的php实现
2013/06/18 PHP
win7 wamp 64位 php环境开启curl服务遇到的问题及解决方法
2018/09/16 PHP
PHP面向对象程序设计重载(overloading)操作详解
2019/06/13 PHP
JavaScript XML实现两级级联下拉列表
2008/11/10 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
node.js中watch机制详解
2014/11/17 Javascript
使用jQuery jqPlot插件绘制柱状图
2014/12/18 Javascript
bootstrap组件之导航组件使用方法
2017/01/19 Javascript
flexslider.js实现移动端轮播
2017/02/05 Javascript
jQuery ajax动态生成table功能示例
2017/06/14 jQuery
bootstrap3中container与container_fluid外层容器的区别讲解
2017/12/04 Javascript
Javascript中弹窗confirm与prompt的区别
2018/10/26 Javascript
vue中进行微博分享的实例讲解
2019/10/14 Javascript
[51:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
[54:43]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第一场 2月22日
2021/03/11 DOTA
python 开发的三种运行模式详细介绍
2017/01/18 Python
python 链接和操作 memcache方法
2017/03/04 Python
pycharm配置pyqt5-tools开发环境的方法步骤
2019/02/11 Python
Python二叉搜索树与双向链表转换算法示例
2019/03/02 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
通过Turtle库在Python中绘制一个鼠年福鼠
2020/02/03 Python
django之从html页面表单获取输入的数据实例
2020/03/16 Python
基于selenium及python实现下拉选项定位select
2020/07/22 Python
css3实现一个div设置多张背景图片及background-image属性实例演示
2017/08/10 HTML / CSS
Daisy London官网:英国最大的首饰集团IBB旗下
2019/02/28 全球购物
C语言如何决定使用那种整数类型
2016/11/26 面试题
机电专业大学生职业规划书范文
2014/02/25 职场文书
师德师风演讲稿
2014/05/05 职场文书
求职自我评价范文100字
2014/09/23 职场文书
故意伤害人身损害赔偿协议书
2014/11/19 职场文书
2015年党员自我剖析材料
2014/12/17 职场文书
幼儿园教学工作总结2015
2015/05/12 职场文书
医院病假条怎么写
2015/08/17 职场文书
机关干部作风整顿心得体会
2016/01/22 职场文书
Nginx静态压缩和代码压缩提高访问速度详解
2022/05/30 Servers