具有自定义哈希行为的 python 对象集

2023-12-10

我想使用一个集合来管理“myItem”实例的集合。 myItem 类有自己的哈希函数。 这些项目的哈希值基于每个项目中的部分数据,但不是全部数据,为简单起见,在下面的示例中,“数据”是字典 r。哈希考虑了 2 个键 hk1 和 hk2,还有第三个键“sad”在哈希计算中未考虑。

class myItem():

    def __init__(self, r):
        # r is a dict holding information about the instance
        # of course r has to have certain keys...
        self.r = r

    def __hash__(self):
        """Override the default hash behavior"""
        return hash(tuple(sorted([self.r['hk1'],self.r['hk2']])))

    def __eq__(self,other):
        """checking equality"""
        if isinstance(other, self.__class__):
            return self.__hash__() == other.__hash__()
        return NotImplemented

    def __ne__(self, other):
        """checking inequality"""
        if isinstance(other, self.__class__):
            return not self.__eq__(other)
        return NotImplemented

    def __repr__(self):
        return str(self.r)

下面的简短单元测试证实了预期的行为。

class testMySet(unittest.TestCase):

    def testMyItemstuff(self):

        m1 = myItem({'hk1':'val1', 'hk2': 100, 'sad': 'other stuff'})
        m2 = myItem({'hk1': 'val1', 'hk2': 100, 'sad': 'different other stuff'})

        self.assertEqual(m1, m2)
        self.assertNotEqual(m1.r['sad'], m2.r['sad'])

        s = { m1 }
        # add m2 to s
        s.add(m2)
        # same hash, m2 is not added
        self.assertEqual(len(s), 1)
        # set contains the original object, not the last one added
        self.assertNotEqual(s.pop().r['sad'], 'different other stuff')

我的问题是,如何修改行为,以便添加一个散列与现有对象一致的新对象最终取代原始对象,同时对性能影响最小?


以这种方式定义哈希对您的应用程序是否有意义确实由您决定,但这似乎不太可能。

无论如何,我可以想到两个选项“与”集合一样快 - O(1) 而不是 O(n) - 它们的速度取决于实现您所描述的哈希函数:

首先,简化您的类并创建实例:

class Item():
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __hash__(self):
        return hash(self.a)

    def __eq__(self,other):
        if isinstance(other, self.__class__):
            # Ignoring .b attribute
            return self.a == other.a
        else:
            return NotImplemented

    def __repr__(self):
        return "Item(%s, %s)" % (self.a, self.b)

i1 = Item(1,2)
i2 = Item(3,4)
i3 = Item(1,5)


print(i1 == i2)             # False (.a's don't match)
print(i1 == i3)             # True  (.a's match)

方法一:字典值

# Using a dict
updating_set = {}
updating_set[i1] = i1       # .values(): [Item(1, 2)]
updating_set[i2] = i2       # .values(): [Item(1, 2), Item(3, 4)]
updating_set[i3] = i3       # .values(): [Item(1, 5), Item(3, 4)]

print(list(updating_set.values()))
# [Item(1, 5), Item(3, 4)]

方法2:使用集合子类

# Using a set subclass
class UpdatingSet(set):
    def add(self, item):
        if item in self: super().remove(item)
        super().add(item)

uset = UpdatingSet()
uset.add(i1)                # UpdatingSet({Item(1, 2)})
uset.add(i2)                # UpdatingSet({Item(1, 2), Item(3, 4)})
uset.add(i3)                # UpdatingSet({Item(1, 5), Item(3, 4)})

奖励方法 3:不需要特殊的哈希函数

class NewItem():
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return "Item(%s, %s)" % (self.a, self.b)

class ItemSet():
    def __init__(self):
        self.items = {}

    def add(self, item):
        item_hash = item.a
        self.items[item_hash] = item

    def values(self):
        return self.items.values()

i1 = NewItem(1,2)
i2 = NewItem(3,4)
i3 = NewItem(1,5)

iset = ItemSet()
iset.add(i1)                # .values(): [Item(1, 2)]
iset.add(i2)                # .values(): [Item(1, 2), Item(3, 4)]
iset.add(i3)                # .values(): [Item(1, 5), Item(3, 4)]

print(list(iset.values()))  # [Item(1, 5), Item(3, 4)]

第三种方法不需要您实施hash(这可能会导致意想不到的副作用,但模仿内部的哈希过程ItemSet.add(),使用“哈希函数”作为字典键。

这可能是你最好的选择,除非你really想要实施哈希并了解该决定的影响程度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有自定义哈希行为的 python 对象集 的相关文章

  • openpyxl 2.4.2:保存后公式生成的单元格值为空

    我使用 openpyxl 打开文件 编辑一些单元格并保存更改 这是一个例子 import openpyxl book openpyxl load workbook sheet path sheet book active for row i
  • 如何在 Ubuntu 上安装 Python 模块

    我刚刚用Python写了一个函数 然后 我想将其做成模块并安装在我的 Ubuntu 11 04 上 这就是我所做的 创建 setup py 和 function py 文件 使用 Python2 7 setup py sdist 构建分发文
  • 如何用 python 和 sympy 解决多元不等式?

    我对使用 python 和 Sympy 还很陌生 并且遇到了使用 sympy 解决多元不等式的问题 假设我的文件中有很多函数 如下所示 cst sqrt x 2 cst exp sqrt cst x 1 4 log log sqrt cst
  • 如何将条目中的部分文本加粗并更改其背景颜色?

    我正在创建一个基于 Tkinter 的 GUI 它有一个 Entry 小部件 我想将其文本的一部分加粗并更改其背景颜色 但我不知道我该怎么做 如果我使用文本小部件 我可以只使用标签 但看起来它们不能与条目小部件一起使用 此代码使用文本小部件
  • 在 Python 中使用 sec 函数的反函数

    我正在创建一个程序 用于计算从一定高度范围和设定初始速度发射射弹的最佳角度 在我需要使用的最终方程中 存在一个反 sec 函数 它导致了一些麻烦 我已经导入了数学并尝试使用 asec 无论如何 但是数学似乎无法计算反秒函数 我也明白 sec
  • Python 中 genfromtxt() 的可变列数?

    我有一个 txt具有不同长度的行的文件 每一行都是代表一条轨迹的一系列点 由于每条轨迹都有自己的长度 因此各行的长度都不同 也就是说 列数从一行到另一行不同 据我所知 genfromtxt Python 中的模块要求列数相同 gt gt g
  • Sorted(key=lambda: ...) 背后的语法[重复]

    这个问题在这里已经有答案了 我不太明白背后的语法sorted 争论 key lambda variable variable 0 Isn t lambda随意的 为什么是variable在看起来像的内容中陈述了两次dict 我认为这里的所有
  • 无法包含外部 pandas 文档 Pycharm v--2018.1.2

    我无法包含外部 pandas 文档Pycharm v 2018 1 2 例如 numpy gt http docs scipy org doc numpy reference generated module name element na
  • Python:当前目录是否自动包含在路径中?

    Python 3 4 通过阅读其他一些 SO 问题 似乎如果moduleName py文件位于当前目录之外 如果要导入它 必须将其添加到路径中sys path insert 0 path to application app folder
  • 唯一的图像哈希值即使 EXIF 信息更新也不会改变

    我正在寻找一种方法来为 python 和 php 中的图像创建唯一的哈希值 我考虑过对原始文件使用 md5 和 因为它们可以快速生成 但是当我更新 EXIF 信息 有时时区关闭 时 它会更改总和 并且哈希也会更改 有没有其他方法可以为这些文
  • 反加入熊猫

    我有两个表 我想附加它们 以便仅保留表 A 中的所有数据 并且仅在其键唯一时添加表 B 中的数据 键值在表 A 和 B 中是唯一的 但在某些情况下键将出现在表 A 和 B 中 我认为执行此操作的方法将涉及某种过滤联接 反联接 以获取表 B
  • Python While 循环,and (&) 运算符不起作用

    我正在努力寻找最大公因数 我写了一个糟糕的 运算密集型 算法 它将较低的值减一 使用 检查它是否均匀地划分了分子和分母 如果是 则退出程序 但是 我的 while 循环没有使用 and 运算符 因此一旦分子可整除 它就会停止 即使它不是正确
  • 在 Mac 上安装 Pygame 到 Enthought 构建中

    关于在 Mac 上安装 Pygame 有许多未解答的问题 但我将在这里提出我的具体问题并希望得到答案 我在 Mac 上安装 Pygame 时遇到了难以置信的困难 我使用 Enthought 版本 EPD 7 3 2 32 位 它是我的默认框
  • 在 Windows 上使用 IPython 笔记本时出现 500 服务器错误

    我刚刚在 Windows 7 Professional 64 位上全新安装了 IPython 笔记本 我采取的步骤是 从以下位置安装 Python 3 4 1http python org http python org gt pip in
  • urllib2.urlopen() 是否实际获取页面?

    当我使用 urllib2 urlopen 时 我在考虑它只是为了读取标题还是实际上带回整个网页 IE 是否真的通过 urlopen 调用或 read 调用获取 HTML 页面 handle urllib2 urlopen url html
  • 负整数的Python表示

    gt gt gt x 4 gt gt gt print b format x x 4 100 gt gt gt mask 0xFFFFFFFF gt gt gt print b format x mask x mask 4294967292
  • WindowsError:[错误 5] 访问被拒绝

    我一直在尝试终止一个进程 但我的所有选项都给出了 Windows 访问被拒绝错误 我通过以下方式打开进程 一个python脚本 test subprocess Popen sys executable testsc py 我想杀死那个进程
  • 是否可以写一个负的python类型注释

    这可能听起来不合理 但现在我需要否定类型注释 我的意思是这样的 an int Not Iterable a string Iterable 这是因为我为一个函数编写了一个重载 而 mypy 不理解我 我的功能看起来像这样 overload
  • Google App Engine 中的自定义身份验证

    有谁知道或知道我可以在哪里学习如何使用 Python 和 Google App Engine 创建自定义身份验证流程 我不想使用 Google 帐户进行身份验证 并且希望能够创建自己的用户 如果不是专门针对 Google App Engin
  • 如何对字符串列表进行排序?

    在 Python 中创建按字母顺序排序的列表的最佳方法是什么 基本回答 mylist b C A mylist sort 这会修改您的原始列表 即就地排序 要获取列表的排序副本而不更改原始列表 请使用sorted http docs pyt

随机推荐

  • 我应该在 href="" 中使用 & 还是在 HTML4 和 HTML5 中 & 就足够了?

    我应该使用 amp in href or HTML4 和 HTML5 就够了吗 大多数浏览器都没有问题 但是应该如何完成呢 a href param1 1 param2 2 Call a Or a href quest param1 1 a
  • 从 Tkinter Tcl 回调 python 函数在 Windows 中崩溃

    这不完全是我的应用程序 但非常相似 我创建了这个测试代码来显示问题 基本上我试图从 python 线程调用 tcl proc 当结果准备好时 Tcl proc 将回调到 python 函数 该结果将作为事件发布到 wx 框架 当我作为纯 p
  • Android发布密钥库问题:“密钥库被篡改,或密码不正确”

    几个月前 我使用以下命令生成了 Android 版本密钥库 keytool genkey v keystore my release key keystore alias myalias keyalg RSA keysize 2048 va
  • 从最新到最旧读取事件日志

    我编写了一个简短的程序 使用启动和关闭时发布的事件日志消息来确定远程 PC 的正常运行时间 目前的逻辑是 foreach eventlogentry if entryTime gt OldestTime if entry Startup a
  • Spring MVC不加载css、js文件到静态html页面

    我禁用了该角色内部视图解析器为了访问一些静态页面 html not jsp页面 我做了所需的更改 确实我做了并且我可以访问我的html页面 但是当我看到浏览器的控制台时 它看起来好像没有带来我的本地css and js files 这是我的
  • 在 Ruby 中访问 JSON 对象 [关闭]

    Closed 这个问题需要调试细节 目前不接受答案 我有一个 json 文件 看起来像这样 Results Lookup null Result Paths Domain VALUE1 LTD Url Text1 Modules Name
  • 如何编辑文件夹/文件的修改日期?

    我正在使用 webdav 和 HttpWebRequest MKCOL 方法在 SP 中创建文件夹 我使用 WebClient 上传文件 对于上传的文件和创建的文件夹 如何设置其修改日期 我正在寻找类似的东西Directory SetLas
  • Swift 5:转义闭包捕获“inout”参数

    我已经有了从服务器收到的响应数据 这个响应数据有一些面包师数据 现在我想计算用户和面包店的距离 然后将其存储在同一个模态类中 我为它创建了一个函数 由于这个函数需要在 4 5 视图控制器中使用 我的计划是创建为 UIViewControll
  • 如何在 Python 中使用 ctypes 卸载 DLL?

    我正在使用 ctypes 在 Python 中加载 DLL 这很好用 现在我们希望能够在运行时重新加载该 DLL 直接的方法似乎是 1 卸载DLL 2 加载DLL 不幸的是我不确定卸载 DLL 的正确方法是什么 ctypes FreeLib
  • 创建自定义 Powershell 对象的多个实例

    我正在 Powershell 脚本中创建一个新对象 或者实际上是一个对象类型 我想创建该对象的多个实例 我该怎么做呢 下面的代码是我正在处理的代码 看起来数组中的所有实例都引用相同的对象 包含相同的值 Define output objec
  • DART:有人可以向我解释一下这句话吗?

    我正在学习 Dart 和 Flutter 但我正在努力解决一些基本的编程问题 例如 getter 的使用 GoogleSignInAccount get user gt user 与 get 方法等效的是什么 什么是 变量末尾的意思是什么
  • 在 Sublime Text 2 中使用默认的 ruby​​ 版本

    我的默认当前 ruby 版本是 1 9 3 它实际上是我运行时出现的唯一版本rvm list所以我不明白我怎么能把那部分搞乱 我确实关注了this我在这里找到的教程 但它似乎破坏了一切 对于我看到的修复程序的所有变体 甚至在评论中 我不断收
  • 通过 AWS Data Pipelines 运行 python 脚本

    我使用 AWS Data Pipelines 运行夜间 SQL 查询 以填充表以获取摘要统计信息 用户界面有点时髦 但最终我安装并运行了 现在我想用 python 脚本做类似的事情 我有一个每天早上在笔记本电脑上运行的文件 forecast
  • 是否可以在不使用 lambda 的情况下将标准函数模板之一作为参数传递?

    例如 std get
  • PDO-MySQL:在准备好的语句绑定上布尔值被转换为 1 或空字符串

    我正在尝试将一些布尔值插入到 JSON 类型列中 taskSql INSERT INTO Tasks data taskListId VALUES JSON OBJECT title title done done taskListId t
  • UICollectionView 单元格与图像,单击更改背景

    我有一个UICollectionView with Custom CollectionView Cells 每个Cell上都有一个Image 它和整个Cell一样大 现在我想在用户触摸单元格时突出显示该单元格 首先我尝试了以下方法deleg
  • Apps 脚本与 Chrome 扩展:编写 Google 文档的替代拼写检查器

    Say 我想开发一个替代谷歌文档的拼写检查模块 这意味着我必须从后端获取更正 并对拼写错误的文本的背景进行着色 并在用户将鼠标悬停在其上方时弹出一个小气泡 在其中显示更正 请注意 拼写检查不是我项目的实际目标 但它确实以更简化的方式解决了我
  • 计算 Pandas 中字符串列中的单词数

    我有一个 pandas 数据框 其中包含给定时间段的查询和计数 我希望将此数据框转换为唯一单词的计数 例如 如果数据框包含以下内容 query count foo bar 10 super 8 foo 4 super foo bar 2 我
  • 外部表的格式不符合预期。

    我正在创建一个小应用程序来将 Excel 数据导入我的数据库 当我单击按钮时 它崩溃并出现错误 外部表的格式不符合预期 我尝试在谷歌上搜索并更改代码 但问题仍然出现 我尝试将文件另存为 xls 当我运行代码时 页面与 google chro
  • 具有自定义哈希行为的 python 对象集

    我想使用一个集合来管理 myItem 实例的集合 myItem 类有自己的哈希函数 这些项目的哈希值基于每个项目中的部分数据 但不是全部数据 为简单起见 在下面的示例中 数据 是字典 r 哈希考虑了 2 个键 hk1 和 hk2 还有第三个