字典界面 [英] dictionary interface

查看:46
本文介绍了字典界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个Tree类,它应该像字典一样。


为了测试这个,我从源代码发布中获取了unittest

用于词典并用它来测试我的Tree类。


事情进展顺利,但我偶然发现了一个问题。

此单元测试尝试测试''==''和''<''运算符。但是我没有在文档中找到任何定义

字典应该对这些运算符的行为的内容。


目前我能想出的最好的东西是

以下内容:


类树:


def __lt __(self,term):

return set(self.iteritems())< set(term.iteritems())

def __eq __(self,term):

return set(self.iteritems())== set(term .iteritems())


这是对所需行为的正确定义吗?


有人参考吗?


-

Antoon Pardon

I''m writing a Tree class, which should behave a lot like a dictionary.

In order to test this, I took the unittest from the source distribution
for dictionaries and used it to test against my Tree class.

Things are working out rather well, but I stumbled on a problem.

this unittest tries to test for ''=='' and ''<'' operators. However I
couldn''t find anything in the documentation that defined how
dictionaries should behave with respect to these operators.

For the moment the best I can come up with is something like
the following:

class Tree:

def __lt__(self, term):
return set(self.iteritems()) < set(term.iteritems())

def __eq__(self, term):
return set(self.iteritems()) == set(term.iteritems())

Would this be a correct definition of the desired behaviour?

Anyone a reference?

--
Antoon Pardon

推荐答案

Antoon Pardon写道:
Antoon Pardon wrote:
我正在编写一个Tree类,它应该像字典一样。

为了测试这个,我从源代码发行版中获取了单元测试用于词典并使用它测试我的Tree课程。

事情进展顺利,但我偶然发现了一个问题。

这个单元测试试图测试''==''和''<''运营商。但是我在文档中找不到任何定义
字典应该如何对这些操作符表现的内容。

目前我能想到的最好的是类似
以下内容:

类树:

def __lt __(自我,术语):
返回集(self.iteritems())< ; set(term.iteritems())

def __eq __(self,term):
return set(self.iteritems())== set(term.iteritems())

这是对所需行为的正确定义吗?


No.


在[1]中:{1:2}< {3:4}

Out [1]:True


在[2]中:set({1:2} .iteritems())< set({3:4} .iteritems())

Out [2]:False

有人参考吗?
I''m writing a Tree class, which should behave a lot like a dictionary.

In order to test this, I took the unittest from the source distribution
for dictionaries and used it to test against my Tree class.

Things are working out rather well, but I stumbled on a problem.

this unittest tries to test for ''=='' and ''<'' operators. However I
couldn''t find anything in the documentation that defined how
dictionaries should behave with respect to these operators.

For the moment the best I can come up with is something like
the following:

class Tree:

def __lt__(self, term):
return set(self.iteritems()) < set(term.iteritems())

def __eq__(self, term):
return set(self.iteritems()) == set(term.iteritems())

Would this be a correct definition of the desired behaviour?
No.

In [1]: {1:2} < {3:4}
Out[1]: True

In [2]: set({1:2}.iteritems()) < set({3:4}.iteritems())
Out[2]: False
Anyone a reference?




函数dict_compare在dictobject.c中。


-

Robert Kern
rk *** @ ucsd.edu


在草地长得高的地狱里

是否允许死亡的坟墓死亡。

- Richard Harter



The function dict_compare in dictobject.c .

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter


2005年10月4日星期二, Robert Kern写道:
On Tue, 4 Oct 2005, Robert Kern wrote:
Antoon Pardon写道:
Antoon Pardon wrote:
class Tree:

def __lt __(self,term) :
返回集(self.iteritems())< set(term.iteritems())

def __eq __(self,term):
return set(self.iteritems())== set(term.iteritems())

这是对所需行为的正确定义吗?
class Tree:

def __lt__(self, term):
return set(self.iteritems()) < set(term.iteritems())

def __eq__(self, term):
return set(self.iteritems()) == set(term.iteritems())

Would this be a correct definition of the desired behaviour?



在[1]中:{1:2}< {3:4}
Out [1]:正确

在[2]中:set({1:2} .iteritems())< set({3:4} .iteritems())
Out [2]:False



No.

In [1]: {1:2} < {3:4}
Out[1]: True

In [2]: set({1:2}.iteritems()) < set({3:4}.iteritems())
Out[2]: False

任何人参考?



函数dict_compare在dictobject.c中。



The function dict_compare in dictobject.c .




嗯,这是一个非常有用的答案。我很好奇,罗伯特 - 因为你知道这个问题的真正答案,你为什么选择告诉他们这是错的,而不是告诉他以何种方式他错了,当然不会告诉他如何做对,只是告诉他阅读消息来源,而不是简单地告诉他你知道什么?尽管如此,至少你告诉他要查看哪个
文件。如果他知道python而不是C,或者在解释器的

byzantine工作中迷失了,那么,这是他自己的错,我估计是b $ b。


所以,Antoon,首先,你认为__eq__的实施是正确的。


遗憾的是,__lt__的实现并非如此。虽然集合采用<意思是

是一个适当的子集,对于dicts来说,它是一个更传统的比较

操作,它构成了所有dicts的总排序(所以你可以

与它排序,例如)。但是,由于dicts并没有真正的自然总排序,所以它有点随意。


对dicts的订购规则是, AFAICT:


- 如果一个字典中的元素少于另一个字典,则它是较小的

- 如果不是,请找到最小的字符串两个dicts有不同的

值(计算''不存在''作为一个值)

- 如果没有这样的密钥,那么dicts是相等的

- 如果密钥存在于一个字典而不是另一个字典中,则存在的字典是

它是较小的

- 否则,值较小的字典本身就是较小的


代码:


def dict_cmp(a,b):

diff = cmp(len(a),len(b))

if(diff!= 0):

return diff

为key in sorted(set(a.keys()+ b.keys())):

if(key not in a):

返回1

如果(键不在b中):

返回-1

diff = cmp(a [key],b [key])

if(diff!= 0):

return diff

return 0


我假设你的树的项目按键值排序;这意味着有一个有效的实现,使用锁步迭代比较两个

树。


另一个看待它的方式是在列表比较方面:比较

两个dicts与比较每个字典中的键排序列表相同,

通过查看打破关系按键顺序排列的值列表。

有一个怪癖,因为较短的字典总是少于一个较长的字典,

无论元素如何。


代码:


def dict_cmp_alternative(a,b):

diff = cmp(len( a),len(b))

if(diff!= 0):

return diff

ka = sorted(a.keys( ))

kb =已排序(b.keys())

diff = cmp(ka,kb)

if(diff!= 0 ):

返回差异

va = [a [k]为k in ka]

vb = [b [k] for k in kb]

返回cmp(va,vb)


希望这会有所帮助。


tom


PS如果它对你有用,这里是我用来测试这些的代码:


import random


def rnd(n):

返回random.randint(0,n)


def randomdict(maxlen = 20,范围= 100):

返回dict((rnd(范围),rnd(范围))x in xrange(rnd(maxlen)))


def测试(cmp2,n = 1000):
$ x $ b for x in xrange(n):

a = randomdict()

b = randomdict()

if((cmp(a,b))!=(cmp2(a,b))):

引发AssertionError,(a,b)


-

我们所了解的不是大自然本身,而是大自然暴露于我们的质疑方法。 - Werner Heisenberg



Well there''s a really helpful answer. I''m intrigued, Robert - since you
know the real answer to this question, why did you choose to tell the
Antoon that he was wrong, not tell him in what way he was wrong, certainly
not tell him how to be right, but just tell him to read the source, rather
than simply telling him what you knew? Still, at least you told him which
file to look in. And if he knows python but not C, or gets lost in the
byzantine workings of the interpreter, well, that''s his own fault, i
guess.

So, Antoon, firstly, your implementation of __eq__ is, i believe, correct.

Your implementation of __lt__ is, sadly, not. While sets take "<" to mean
"is a proper subset of", for dicts, it''s a more conventional comparison
operation, which constitutes a total ordering over all dicts (so you can
sort with it, for example). However, since dicts don''t really have a
natural total ordering, it is ever so slightly arbitrary.

The rules for ordering on dicts are, AFAICT:

- If one dict has fewer elements than the other, it''s the lesser
- If not, find the smallest key for which the two dicts have different
values (counting ''not present'' as a value)
-- If there is no such key, the dicts are equal
-- If the key is present in one dict but not the other, the dict in which
it is present is the lesser
-- Otherwise, the dict in which the value is lesser is itself the lesser

In code:

def dict_cmp(a, b):
diff = cmp(len(a), len(b))
if (diff != 0):
return diff
for key in sorted(set(a.keys() + b.keys())):
if (key not in a):
return 1
if (key not in b):
return -1
diff = cmp(a[key], b[key])
if (diff != 0):
return diff
return 0

I assume your tree has its items sorted by key value; that means there''s
an efficient implementation of this using lockstep iteration over the two
trees being compared.

Another way of looking at it is in terms of list comparisons: comparing
two dicts is the same as comparing the sorted list of keys in each dict,
breaking ties by looking at the list of values, in order of their keys.
There''s a quirk, in that a shorter dict is always less than a longer dict,
regardless of the elements.

In code:

def dict_cmp_alternative(a, b):
diff = cmp(len(a), len(b))
if (diff != 0):
return diff
ka = sorted(a.keys())
kb = sorted(b.keys())
diff = cmp(ka, kb)
if (diff != 0):
return diff
va = [a[k] for k in ka]
vb = [b[k] for k in kb]
return cmp(va, vb)

Hope this helps.

tom

PS In case it''s of any use to you, here''s the code i used to test these:

import random

def rnd(n):
return random.randint(0, n)

def randomdict(maxlen=20, range=100):
return dict((rnd(range), rnd(range)) for x in xrange(rnd(maxlen)))

def test(cmp2, n=1000):
for i in xrange(n):
a = randomdict()
b = randomdict()
if ((cmp(a, b)) != (cmp2(a, b))):
raise AssertionError, (a, b)

--
What we learn about is not nature itself, but nature exposed to our methods of questioning. -- Werner Heisenberg


Tom Anderson写道:
Tom Anderson wrote:
2005年10月4日星期二,Robert Kern写道:
On Tue, 4 Oct 2005, Robert Kern wrote:
Antoon Pardon写道:
Antoon Pardon wrote:
类树:

def __lt __(self,term):
返回集(self.iteritems( ))< set(term.iteritems())

def __eq __(self,term):
return set(self.iteritems())== set(term.iteritems())

这是否是对所需行为的正确定义?


在[1]中:{1:2}< {3:4}
Out [1]:正确

在[2]中:set({1:2} .iteritems())< set({3:4} .iteritems())
Out [2]:False
class Tree:

def __lt__(self, term):
return set(self.iteritems()) < set(term.iteritems())

def __eq__(self, term):
return set(self.iteritems()) == set(term.iteritems())

Would this be a correct definition of the desired behaviour?
No.

In [1]: {1:2} < {3:4}
Out[1]: True

In [2]: set({1:2}.iteritems()) < set({3:4}.iteritems())
Out[2]: False
任何人参考?



函数dict_compare在dictobject.c中。



The function dict_compare in dictobject.c .



那里有一个非常有用的答案。



Well there''s a really helpful answer.




好​​吧,*我*认为这是。也许不是真的很有帮助,但肯定是一个健康的开始。

我很好奇,罗伯特 - 因为你知道这个问题的真正答案,你为什么选择告诉安东尼他错了,不要告诉他他错在哪,他当然不会告诉他怎么做对,而只是告诉他读源,而不是
而不是简单地告诉他你知道什么?


因为我*不知道。我*还是*不知道。我只知道__lt__的

实现是错误的,因为我通过将

给定算法应用于真实字典来证明。我*做*知道在哪里找到

信息:来源。所以我告诉他绝对我知道的所有关于这个主题的
。我不能告诉他任何更多的东西,除非通过我自己的来源细节跋涉

,但我不是特别想要自己学习这些细节的b $ b所以我没有打扰。


你想要什么?由candygram提供的个性化Python教程?

各种部分订购方案的详细比较可能已经使用了?b $ b?我的第一个出生的儿子?

仍然,至少你告诉他要查看哪个文件。


是的,我认为这是礼貌的,有用的事情。显然,我不会打扰他们。

如果他知道python而不是C,或者在解释器的拜占庭工作中迷路了,好吧,这是他自己的错,我猜错了。



Well, *I* thought it was. Maybe not "really" helpful, but certainly a
healthy start.
I''m intrigued, Robert - since you
know the real answer to this question, why did you choose to tell the
Antoon that he was wrong, not tell him in what way he was wrong, certainly
not tell him how to be right, but just tell him to read the source, rather
than simply telling him what you knew?
Because I *didn''t* know. I *still* don''t know. I just know that the
implementation of __lt__ was wrong as I demonstrated by applying the
given algorithm to real dictionaries. I *do* know where to find that
information: the source. So I told him absolutely everything that I knew
on the subject. I couldn''t tell him anything more except by trudging
through the details of the source myself, but I''m not particularly
interested in learning those details myself, so I didn''t bother.

What do you want? Personalized Python tutorials delivered by candygram?
A detailed comparison of the various partial ordering schemes that could
have been used? My first born son?
Still, at least you told him which
file to look in.
Yes, I figured it was the polite, helpful thing to do. Apparently, I
shouldn''t have bothered.
And if he knows python but not C, or gets lost in the
byzantine workings of the interpreter, well, that''s his own fault, i
guess.




这肯定不是我的。


-

Robert Kern
rk***@ucsd.edu


在地狱的地方,草地长得很高

梦想的坟墓是否能够死亡。

- - Richard Harter



It''s certainly not mine.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter


这篇关于字典界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆