在Python 2.6解释器上测试:
>>> a=set('abcde')
>>> a
set(['a', 'c', 'b', 'e', 'd'])
>>> l=['f','g']
>>> l
['f', 'g']
>>> a.add(l)
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
a.add(l)
TypeError: list objects are unhashable
Run Code Online (Sandbox Code Playgroud)
我认为我无法将列表添加到集合中,因为Python无法判断如果我已经两次添加相同的列表.有解决方法吗?
编辑:我想添加列表本身,而不是其元素.
这段代码给我一个错误unhashable type: dict,任何人都可以解释我的解决方案是什么
negids = movie_reviews.fileids('neg')
def word_feats(words):
return dict([(word, True) for word in words])
negfeats = [(word_feats(movie_reviews.words(fileids=[f])), 'neg') for f in negids]
stopset = set(stopwords.words('english'))
def stopword_filtered_word_feats(words):
return dict([(word, True) for word in words if word not in stopset])
result=stopword_filtered_word_feats(negfeats)
Run Code Online (Sandbox Code Playgroud) 我偶然发现了一篇博文,详细介绍了如何在Python中实现powerset函数.所以我开始尝试自己的方式,并发现Python显然不能有一组集合,因为set不可清除.这是令人厌烦的,因为powerset的定义是它是一组集合,我想使用实际的集合操作来实现它.
>>> set([ set() ])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
Run Code Online (Sandbox Code Playgroud)
有没有一个很好的理由Python设置不可用?
我需要扩展Networkx python包并Graph为我的特殊需要添加一些方法
我想这样做的方法是简单地推导出一个新类说NewGraph,并添加所需的方法.
然而,networkx中还有一些其他函数可以创建和返回Graph对象(例如,生成随机图).我现在需要将这些Graph对象转换为NewGraph对象,以便我可以使用我的新方法.
这样做的最佳方式是什么?或者我应该以完全不同的方式解决问题?
任何人都有一些简洁的字典示例,其中包含一些有趣的键(除了规范字符串或整数),以及您在程序中如何使用它们?
我理解一个关键所需要的东西hashable,意味着它必须是不可变的和可比较的(有一个__eq__()或一个__cmp__()方法).
一个相关的问题是:我怎样才能快速,轻松地定义一个新的hashable?
我需要实现一个hashable dict,所以我可以使用字典作为另一个字典的键.
几个月前我使用了这个实现:Python hashable dicts
但是我收到一位同事的通知说"这不是真的不可变,因此不安全.你可以使用它,但它确实让我感觉像一个悲伤的熊猫'.
所以我开始四处寻找创造一个不可变的东西.我没有必要将'key-dict'与另一个'key-dict'进行比较.它唯一的用途是作为另一个字典的关键.
我想出了以下内容:
class HashableDict(dict):
"""Hashable dict that can be used as a key in other dictionaries"""
def __new__(self, *args, **kwargs):
# create a new local dict, that will be used by the HashableDictBase closure class
immutableDict = dict(*args, **kwargs)
class HashableDictBase(object):
"""Hashable dict that can be used as a key in other dictionaries. This is now immutable"""
def __key(self):
"""Return a tuple of the current keys"""
return tuple((k, immutableDict[k]) for k in sorted(immutableDict)) …Run Code Online (Sandbox Code Playgroud) 我目前正在尝试理解为Python的内置frozenset数据类型定义的哈希函数背后的机制.实施情况显示在底部以供参考.我特别感兴趣的是选择这种散射操作的基本原理:
lambda h: (h ^ (h << 16) ^ 89869747) * 3644798167
Run Code Online (Sandbox Code Playgroud)
h每个元素的哈希值在哪里.有谁知道这些来自哪里?(也就是说,有没有特别的理由选择这些数字?)或者他们只是随意选择?
这是官方CPython实现的片段,
static Py_hash_t
frozenset_hash(PyObject *self)
{
PySetObject *so = (PySetObject *)self;
Py_uhash_t h, hash = 1927868237UL;
setentry *entry;
Py_ssize_t pos = 0;
if (so->hash != -1)
return so->hash;
hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
while (set_next(so, &pos, &entry)) {
/* Work to increase the bit dispersion for closely spaced hash
values. The is important because some use cases have many
combinations of a small number …Run Code Online (Sandbox Code Playgroud) 我有一些日志数据,例如:
logs = [
{'id': '1234', 'error': None, 'fruit': 'orange'},
{'id': '12345', 'error': None, 'fruit': 'apple'}
]
Run Code Online (Sandbox Code Playgroud)
每个字典都有相同的键:'id'、'error'和'fruit'(在本例中)。
我想从此列表中删除重复项,但直接dict且set基于基础的方法不起作用,因为我的元素本身就是dicts,不可散列:
>>> set(logs)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
Run Code Online (Sandbox Code Playgroud)
另一种方法是排序并使用 itertools.groupby - 但字典也不具有可比性,因此这也不起作用:
>>> from itertools import groupby
>>> [k for k, _ in groupby(sorted(logs))]
Traceback (most recent call last):
File "<stdin>", line 1, in <module> …Run Code Online (Sandbox Code Playgroud) 我有两个类(让我们称之为Working和ReturnStatement),我无法修改,但我想用日志记录扩展它们.诀窍是Working的方法返回一个ReturnStatement对象,因此新的MutantWorking对象也返回ReturnStatement,除非我可以将它强制转换为MutantReturnStatement.用代码说:
# these classes can't be changed
class ReturnStatement(object):
def act(self):
print "I'm a ReturnStatement."
class Working(object):
def do(self):
print "I am Working."
return ReturnStatement()
# these classes should wrap the original ones
class MutantReturnStatement(ReturnStatement):
def act(self):
print "I'm wrapping ReturnStatement."
return ReturnStatement().act()
class MutantWorking(Working):
def do(self):
print "I am wrapping Working."
# !!! this is not working, I'd need that casting working !!!
return (MutantReturnStatement) Working().do()
rs = MutantWorking().do() #I can use MutantWorking just like Working
print "--" # …Run Code Online (Sandbox Code Playgroud) 简短版本:作为无序项目字典实现的多集合的最佳散列算法是什么?
我正在尝试将一个不可变的multiset(这是一个包或其他语言的多重集合:像一个数学集,除了它可以容纳多个元素)作为字典实现.我已经创建了标准库类的子类collections.Counter,类似于这里的建议:Python hashable dicts,它建议像这样的哈希函数:
class FrozenCounter(collections.Counter):
# ...
def __hash__(self):
return hash(tuple(sorted(self.items())))
Run Code Online (Sandbox Code Playgroud)
创建完整的项目元组会占用大量内存(相对于使用生成器而言),并且哈希将在我的应用程序的内存密集型部分中发生.更重要的是,我的字典键(multiset元素)可能不会是可订购的.
我正在考虑使用这个算法:
def __hash__(self):
return functools.reduce(lambda a, b: a ^ b, self.items(), 0)
Run Code Online (Sandbox Code Playgroud)
我想使用按位XOR意味着顺序与散列值无关,与元组的散列不同?我想我可以在我的数据的无序流序列上半实现Python元组散列算法.请参阅https://github.com/jonashaag/cpython/blob/master/Include/tupleobject.h(在页面中搜索"hash"一词) - 但我几乎不知道有足够的C来阅读它.
思考?建议?谢谢.
set(),但事情必须是哈希的.)
@marcin和@senderle都给出了相同的答案:使用hash(frozenset(self.items())).这是有道理的,因为items()"视图"是设置的.@marcin是第一个,但我给@senderle打了一个复选标记,因为对不同解决方案的大O运行时间进行了很好的研究.@marcin还提醒我要包含一个__eq__方法 - 但是继承自的方法dict会很好用.这就是我实现所有内容的方式 - 欢迎基于此代码的进一步意见和建议:
class FrozenCounter(collections.Counter):
# Edit: A previous version of this code included a __slots__ definition.
# But, from the Python documentation: "When …Run Code Online (Sandbox Code Playgroud) python ×10
hash ×3
set ×3
dictionary ×2
inheritance ×2
base-class ×1
casting ×1
immutability ×1
list ×1
python-3.2 ×1
python-3.x ×1