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 13 Python
Python Web框架Tornado运行和部署
Oct 19 Python
python+django快速实现文件上传
Oct 24 Python
python实现感知器
Dec 19 Python
Python @property使用方法解析
Sep 17 Python
在OpenCV里实现条码区域识别的方法示例
Dec 04 Python
Python 解决相对路径问题:"No such file or directory"
Jun 05 Python
详解查看Python解释器路径的两种方式
Oct 15 Python
Python基于Serializer实现字段验证及序列化
Nov 04 Python
python中把元组转换为namedtuple方法
Dec 09 Python
Python爬虫入门案例之爬取去哪儿旅游景点攻略以及可视化分析
Oct 16 Python
python字符串的一些常见实用操作
Apr 06 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
动漫定律:眯眯眼都是怪物!这些角色狠话不多~
2020/03/03 日漫
推荐几部必看的DC动画电影
2020/03/03 欧美动漫
ThinkPHP3.2框架自带分页功能实现方法示例
2019/05/13 PHP
JavaScript语言中的Literal Syntax特性分析
2007/03/08 Javascript
Jquery为a标签的href赋值实现代码
2013/05/03 Javascript
js判断FCKeditor内容是否为空的两种形式
2013/05/14 Javascript
div+css+js实现无缝滚动类似marquee无缝滚动兼容firefox
2013/08/29 Javascript
使用 Node.js 做 Function Test实现方法
2013/10/25 Javascript
jquery高级编程的最佳实践详解
2014/03/23 Javascript
jQuery过滤选择器用法分析
2015/02/10 Javascript
浅析jquery数组删除指定元素的方法:grep()
2016/05/19 Javascript
JavaScript中校验银行卡号的实现代码
2016/12/19 Javascript
jQuery插件echarts实现的多折线图效果示例【附demo源码下载】
2017/03/04 Javascript
Ionic + Angular.js实现图片轮播的方法示例
2017/05/21 Javascript
require.js中的define函数详解
2017/07/10 Javascript
详解vue-cli@2.x项目迁移日志
2019/06/06 Javascript
json数据格式常见操作示例
2019/06/13 Javascript
JS实现拖拽元素时与另一元素碰撞检测
2020/08/27 Javascript
[52:57]2014 DOTA2国际邀请赛中国区预选赛 LGD-CDEC VS HGT
2014/05/21 DOTA
Python去掉字符串中空格的方法
2014/03/11 Python
《Python之禅》中对于Python编程过程中的一些建议
2015/04/03 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
python实现大转盘抽奖效果
2019/01/22 Python
python实现维吉尼亚加密法
2019/03/20 Python
Python插入Elasticsearch操作方法解析
2020/01/19 Python
python如何调用百度识图api
2020/09/29 Python
Python包资源下载路径报404解决方案
2020/11/05 Python
Django Model层F,Q对象和聚合函数原理解析
2020/11/12 Python
详解如何修改jupyter notebook的默认目录和默认浏览器
2021/01/24 Python
美国知名的女性服饰品牌:LOFT(洛芙特)
2016/08/05 全球购物
英国口碑最好的的维他命胶囊品牌:Myvitamins(有中文站)
2016/12/03 全球购物
nohup的用法
2014/08/10 面试题
Ajax请求总共有多少种Callback
2016/07/17 面试题
给民警的表扬信
2014/01/08 职场文书
2014年设计师工作总结
2014/11/25 职场文书
python计算列表元素与乘积详情
2022/08/05 Python