- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
每次 heapq.heapify
函数更改我的堆列表中的元素时,我都希望得到回调通知(顺便说一句,这是跟踪列表中的对象以及它们的索引如何获取所需要的改变了)。
我的计划是从 list
继承并重写 __setitem__
方法,我将通过该方法跟踪列表中的更改。所以这是子类:
class List2(list):
def __setitem__(self, key, value):
print 'setitem: key=',key,' value=',value
list.__setitem__(self, key, value)
def __getitem__(self, key):
print 'getitem: key=',key
return list.__getitem__(self, key)
然后我创建一个 List2
的实例并为它调用 heapify:
h = List2([12, -3, 0, 5, 1, 7])
heapq.heapify(h)
问题是重写的 __setitem__
不是从 heapq.heapify
中调用的。看起来 heapq.heapify
将 List2 的实例视为默认列表。我猜这与 heapq.heapify
是一个内置函数有关,但我还是不明白。
为什么 heapq.heapify
没有调用覆盖的 __setitem__
?
这里有趣的是,如果我将 heapq 的代码复制粘贴到我的本地模块中(因此它不再是内置函数),那么它会按预期工作并且我会调用 List2.__settiem__
,但它不适用于默认(内置)heapq
。
Python 2.7 如果重要的话
最佳答案
作为 Python 3.0 项目的一部分,以及 3.3,他们仔细阅读了文档,使得当某些东西采用 list
与一般的 sequence type
时更明确或可变序列类型
或可迭代
,以及heapq
在 3.3 中肯定是说 list
,这意味着在 2.7 中也是如此。
如果您跟踪代码,如果您有 C 实现,在 _heapqmodule.c
, heapify
显式调用 PyList_Check
来验证该类型是一个真正的 list
而不是类似 list
的序列。这不会捕获 list
的子类,但您可以看到它直接调用 PyList_GETSIZE
和(在 _siftup
内)PyList_GET_ITEM
和 PyList_SET_ITEM
,因此它将 list
子类视为基础 list
对象。 (这在当前主干中没有改变。)
因此,有几种解决方法。
首先,正如@FogleBird 所建议的,您可以直接 fork heapq
的纯 Python 实现。 — 只需将完全相同的内容复制到您的项目中,给它一个不同的名称,然后删除第 318-321 行的 from _heapq import *
位。
但是,这可能会慢很多。
从 CPython 切换到 PyPy可能会自动解决该问题(这也意味着无论您是否需要,您都将获得纯 Python 实现)。
事实上,我对包含 1,000,000 项的列表进行了快速测试。在验证 PyPy 实际上确实使用了 List2
类之后,我对其进行了修改,以便将字符串存储到全局变量中,而不是打印。 (否则,打印时间比 Mac 上的实际工作长 3 倍,在 Windows 上长 40 倍……)然后我用各种不同的 Python 运行它:
PyPy 2.7.2/1.9.0 64 位 Mac:1.619s
CPython 2.7.3 32 位赢:3.997 秒
因此,尽管实际上调用了我的 Python 列表重写,但 PyPy 把其他一切都搞砸了。 (我没有测试 Jython 或 IronPython——部分原因是 JVM 或 .NET 的启动和预热时间太长,你需要更长的测试才能公平......但它们也必须使用纯 Python heapq
模块。)
但这可能是一个比您想要做的更显着的改变。另一种选择是也 fork _heapqmodule.c
。即使您根本不了解 C API,这实际上也只是一项搜索和替换工作。对于每个 PyList_FOO
函数,将其替换为相应的 PySequence_Foo
函数(PyList_SIZE
-> PySequence_Size
、PyList_GETITEM
-> PySequence->GetItem
等)。并在出现的两个地方替换模块名称。就是这样。然后构建模块,让你的 fork myheapq.py
尝试 import _myheapq
而不是 import _heapq
。这仍然不会像内置实现那么快,但这只是因为它会多次调用你的 __getitem__
和 __setitem__
方法,这正是你想要的。
关于python - heapq.heapify 不适用于子类列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13924393/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!