为什么dictionary.keys()是一个列表而不是一个集合? [英] Why is dictionary.keys() a list and not a set?

查看:102
本文介绍了为什么dictionary.keys()是一个列表而不是一个集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,答案很简单:由于历史原因 - 内置集只存在

,因为Python 2.4。


无论如何,我在考虑是否有可能并且希望在未来的Python版本中更改旧的行为并让dict.keys()

和dict.values()都返回集而不是列表。


如果d是dict,代码如下:


for x in d.keys():

...


甚至


for x in sorted(d.keys()):

...


仍然可以工作并且也一样。


然而,年长的成语


k = d.keys()

k.sort()

for x in k:

...


会中断(因为你无法直接对地图进行排序)。


所以似乎无法改变行为,因为它会破坏旧的

代码。也许keys()和values()可以被弃用的函数,

被keyset()和valueset()取代,但可能这不值得付出。


另一个相关问题:实际上,dicts可以被视为

子类的集合,因此可以继承很多set方法和

运营商。只有交集和联合必须小心对待,因为词典必须是映射(即映射到一个值)。


实际上,一些继承来自已经实现了集合:


例如,通过允许集合运算符在...中对于字典,

而不是has_key。


len(),clear(),copy()和update()函数也可以是

被解释为继承自set。字典方法popitem()是

实际上是继承的set方法pop()。 (d.pop()没有参数

实际上可以和d.popitem()一样;我猜选后缀item是

来提醒你它返回一个键/值对,而不仅仅是一个值。)


但其他设置方法是否也有用?


字典可以从集合继承remove()和discard()方法。

d.remove(x)与del d [x]相同,但d.discard(x)不会

如果x不在d中,则引发KeyError。


或者,例如,如果


a = {1:11, 2:12}; b = {2:22,3:13},c = {2:32}


然后


c.issubset(b) == c< = b == True

b.issuperset(c)== b> = c == True

a.difference(b)== a - b == {1:11}

assymmetric_difference(b)== a ^ b == {1:11,3:13}

a.update (b)== a | = b == a = {1:11,2:22,3:13}

a.intersection_update(b)== a& = b == a = {2:22}

a.difference_update(b)== a - = b == a = {1:11}

a.symmetric_difference_update(b)= = a ^ = b == a = {1:11,3:13}


其中一个| = b可能特别有趣,因为
$的短符号b $ b a.update(b)。


- Christoph

解决方案

Christoph Zwerschke< ci**@online.de>写道:

好的,答案很简单:由于历史原因 - 内置集仅存在于Python 2.4之后。

无论如何,我在想是否在未来的Python版本中改变旧的行为是可能的,并且让dict.keys()和dict.values()都返回集合而不是列表。


两个(修辞,因为你放弃了这个想法)问题:


你确定dict.values()应该是一套吗?毕竟,值不是保证是唯一的,所以dict(a = 1,b = 1).values()目前

返回[1,1 ],但会在你的提议下返回set([1])。


dict.items()怎么样?

例如,通过允许集合运营商在...中对于词典,
而不是has_key。


" in"已经适用于dicdtionaries:

d = dict(a = 1,b = 1)
' d
中的'a''d
中的'f''错误



但其他设置方法也可以是有用吗?




看起来像。


< mike

-

Mike Meyer< mw*@mired.org> http://www.mired.org/home/mwm/

独立的WWW / Perforce / FreeBSD / Unix顾问,电子邮件以获取更多信息。


Christoph Zwerschke写道:

无论如何,我在考虑是否有可能和希望在未来的Python版本中更改旧的行为,让dict.keys()
和dict.values()都返回集而不是列表。 / blockquote>


你回答的问题是否可行(不,因为

向后兼容性);你不会试图回答这个问题

是否可取。为什么你认为这将是好主意?


如果你想要字典d的键组,那么设置(d):< br>

d = {1:2,3:4}
set(d)



set([1,3])


正如Mike Meyer解释的那样,同样对.values()毫无意义:

他们可能不是唯一的。对于.items(),转换为集合

看起来有意义,但实际上并不起作用:
如果值包含不可用对象,则为
元组

无法构建(因为集合成员必须是不可变的)。


问候,

Martin


你已经可以通过有效的方式从字典的键中获取一个集合:

l = dict.fromkeys(范围(10))
set(l)



Set([0,1,2, 3,4,5,6,7,8,9])


杰夫


-----开始PGP签名 - ---

版本:GnuPG v1.4.1(GNU / Linux)

iD8DBQFDhR6sJd01MZaTXX0RAvz5AJoD02CCRhNt5xsTpZI7rj iVrYUywACfYNzL

vhkMLH1​​qXOV1i8R1Je5cSzk =

= 9crP

-----结束PGP签名-----


Ok, the answer is easy: For historical reasons - built-in sets exist
only since Python 2.4.

Anyway, I was thinking about whether it would be possible and desirable
to change the old behavior in future Python versions and let dict.keys()
and dict.values() both return sets instead of lists.

If d is a dict, code like:

for x in d.keys():
...

or even

for x in sorted(d.keys()):
...

would still work and do the same.

However, the older idiom

k = d.keys()
k.sort()
for x in k:
...

would break (since you cannot sort a map directly).

So it seems not possible to change the behavior since it would break old
code. Maybe keys() and values() could be made deprecated functions,
superseded by keyset() and valueset(), but probably this would not be
worth the effort.

Another related question: Actually, dicts can be considered as
subclasses of sets and thus could inherit a lot of set methods and
operators. Only intersection and union must be treated with care,
because dictionaries must be mappings (i.e. map to exactly one value).

In fact, some inheritance from sets has already been implemented:

For instance, by allowing the set operator "in" for dictionaries,
instead of "has_key".

The len(), clear(), copy() and update() functions can also be
interpreted as inherited from set. The dictionary method popitem() is
actually the inherited set method pop(). (d.pop() without arguments
could actually do the same as d.popitem(); I guess the suffix "item" was
chosen to remind you that it returns a key/value pair, not only a value.)

But could other set methods also be useful?

A dictionary could inherit the remove() and discard() method from sets.
d.remove(x) would do the same as del d[x], but d.discard(x) would not
raise a KeyError if x not in d.

Or, for instance, if

a = { 1:11, 2:12 }; b = { 2:22, 3:13 }, c = { 2:32 }

then

c.issubset(b) == c <= b == True
b.issuperset(c) == b >= c == True
a.difference(b) == a - b == { 1:11 }
a.s.symmetric_difference(b) == a ^ b == { 1:11, 3:13 }
a.update(b) == a |= b == a = { 1:11, 2:22, 3:13 }
a.intersection_update(b) == a &= b == a = { 2:22 }
a.difference_update(b) == a -= b == a = { 1:11 }
a.symmetric_difference_update(b) == a ^= b == a = { 1:11, 3:13 }

Of these, a |= b may be particularly interesting as short notation for
a.update(b).

-- Christoph

解决方案

Christoph Zwerschke <ci**@online.de> writes:

Ok, the answer is easy: For historical reasons - built-in sets exist
only since Python 2.4.

Anyway, I was thinking about whether it would be possible and
desirable to change the old behavior in future Python versions and let
dict.keys() and dict.values() both return sets instead of lists.
Two (rhetorical, since you dropped the idea) questions:

Are you sure dict.values() should be a set? After all, values aren''t
guaranteed to be unique, so dict(a = 1, b = 1).values() currently
returns [1, 1], but would return set([1]) under your proposal.

What about dict.items()?
For instance, by allowing the set operator "in" for dictionaries,
instead of "has_key".
"in" already works for dicdtionaries:

d = dict(a = 1, b = 1)
''a'' in d True ''f'' in d False


But could other set methods also be useful?



Looks like it.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.


Christoph Zwerschke wrote:

Anyway, I was thinking about whether it would be possible and desirable
to change the old behavior in future Python versions and let dict.keys()
and dict.values() both return sets instead of lists.



You answer the question whether it would be possible (no, because of
backwards compatibility); you don''t attempt to answer the question
whether it would be desirable. Why do you think that would be
a good idea?

If you want the set of keys of a dictionary d, then do set(d):

d={1:2,3:4}
set(d)


set([1, 3])

As Mike Meyer explains, the same is meaningless for .values():
they might not be unique. For .items(), conversion into a set
does would appear to be meaningful, but doesn''t actually work:
if the values contain unhashable objects, the set of tuples
cannot be constructed (as set members must be immutable).

Regards,
Martin


You can already get a set from a dictionary''s keys in an efficient manner:

l = dict.fromkeys(range(10))
set(l)


Set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFDhR6sJd01MZaTXX0RAvz5AJoD02CCRhNt5xsTpZI7rj iVrYUywACfYNzL
vhkMLH1qXOV1i8R1Je5cSzk=
=9crP
-----END PGP SIGNATURE-----


这篇关于为什么dictionary.keys()是一个列表而不是一个集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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