1. Abstract(摘要)

This PEP proposes(建议) to change the .keys(), .values() and .items() methods of the built-in dict type to return a set-like or unordered container object whose contents are derived from the underlying(潜在的) dictionary rather than a list which is a copy of the keys, etc.; and to remove the .iterkeys(), .itervalues() and .iteritems() methods.

The approach is inspired(灵感) by that taken in the Java Collections Framework [1].

2.Introduction

It has long been the plan to change the .keys(), .values() and .items() methods of the built-in dict type to return a more lightweight object than a list, and to get rid of .iterkeys(), .itervalues() and .iteritems(). The idea is that code that currently (in 2.x) reads:

for k, v in d.iteritems(): ...
should be rewritten as:

for k, v in d.items(): ...
(and similar for .itervalues() and .iterkeys(), except the latter is redundant since we can write that loop as for k in d.)

Code that currently reads:

a = d.keys() # assume we really want a list here
(etc.) should be rewritten as

a = list(d.keys())
There are (at least) two ways to accomplish(实现) this. The original plan was to simply let .keys(), .values() and .items() return an iterator, i.e. exactly what iterkeys(), itervalues() and iteritems() return in Python 2.x. However, the Java Collections Framework [1] suggests that a better solution is possible: the methods return objects with set behavior (for .keys() and .items()) or multiset (== bag) behavior (for .values()) that do not contain copies of the keys, values or items, but rather reference the underlying dict and pull their values out of the dict as needed.

The advantage(优势) of this approach is that one can still write code like this:

a = d.items()
for k, v in a: ...
# And later, again:
for k, v in a: ...
Effectively, iter(d.keys()) (etc.) in Python 3.0 will do what d.iterkeys() (etc.) does in Python 2.x; but in most contexts we don't have to write the iter() call because it is implied by a for-loop.

在python3.0中,iter(d.keys())等同于python2.0的d.iterkeys()  ,但是,在大多数场景下,我们不需要嗲用iter(),因为,可以使用简单的for循环实现。

list可迭代化,但不是迭代器。

https://stackoverflow.com/questions/45458631/how-python-built-in-function-iter-convert-a-python-list-to-an-iterator

The objects returned by the .keys() and .items() methods behave like sets. The object returned by the values() method behaves like a much simpler unordered collection -- it cannot be a set because duplicate values are possible.

Because of the set behavior, it will be possible to check whether two dicts have the same keys by simply testing:

if a.keys() == b.keys(): ...
and similarly for .items().

These operations are thread-safe only to the extent that using them in a thread-unsafe way may cause an exception but will not cause corruption of the internal representation.

As in Python 2.x, mutating a dict while iterating over it using an iterator has an undefined effect and will in most cases raise a RuntimeError exception. (This is similar to the guarantees made by the Java Collections Framework.)

The objects returned by .keys() and .items() are fully interoperable with instances of the built-in set and frozenset types; for example:

set(d.keys()) == d.keys()
is guaranteed to be True (except when d is being modified simultaneously by another thread).

Specification
I'm using pseudo-code to specify the semantics:

class dict:

# Omitting all other dict methods for brevity.
# The .iterkeys(), .itervalues() and .iteritems() methods
# will be removed.

def keys(self):
return d_keys(self)

def items(self):
return d_items(self)

def values(self):
return d_values(self)

class d_keys:

def __init__(self, d):
self.__d = d

def __len__(self):
return len(self.__d)

def __contains__(self, key):
return key in self.__d

def __iter__(self):
for key in self.__d:
yield key

# The following operations should be implemented to be
# compatible with sets; this can be done by exploiting
# the above primitive operations:
#
# <, <=, ==, !=, >=, > (returning a bool)
# &, |, ^, - (returning a new, real set object)
#
# as well as their method counterparts (.union(), etc.).
#
# To specify the semantics, we can specify x == y as:
#
# set(x) == set(y) if both x and y are d_keys instances
# set(x) == y if x is a d_keys instance
# x == set(y) if y is a d_keys instance
#
# and so on for all other operations.

class d_items:

def __init__(self, d):
self.__d = d

def __len__(self):
return len(self.__d)

def __contains__(self, (key, value)):
return key in self.__d and self.__d[key] == value

def __iter__(self):
for key in self.__d:
yield key, self.__d[key]

# As well as the set operations mentioned for d_keys above.
# However the specifications suggested there will not work if
# the values aren't hashable. Fortunately, the operations can
# still be implemented efficiently. For example, this is how
# intersection can be specified:

def __and__(self, other):
if isinstance(other, (set, frozenset, d_keys)):
result = set()
for item in other:
if item in self:
result.add(item)
return result
if not isinstance(other, d_items):
return NotImplemented
d = {}
if len(other) < len(self):
self, other = other, self
for item in self:
if item in other:
key, value = item
d[key] = value
return d.items()

# And here is equality:

def __eq__(self, other):
if isinstance(other, (set, frozenset, d_keys)):
if len(self) != len(other):
return False
for item in other:
if item not in self:
return False
return True
if not isinstance(other, d_items):
return NotImplemented
# XXX We could also just compare the underlying dicts...
if len(self) != len(other):
return False
for item in self:
if item not in other:
return False
return True

def __ne__(self, other):
# XXX Perhaps object.__ne__() should be defined this way.
result = self.__eq__(other)
if result is not NotImplemented:
result = not result
return result

class d_values:

def __init__(self, d):
self.__d = d

def __len__(self):
return len(self.__d)

def __contains__(self, value):
# This is slow, and it's what "x in y" uses as a fallback
# if __contains__ is not defined; but I'd rather make it
# explicit that it is supported.
for v in self:
if v == value:
return True
return False

def __iter__(self):
for key in self.__d:
yield self.__d[key]

def __eq__(self, other):
if not isinstance(other, d_values):
return NotImplemented
if len(self) != len(other):
return False
# XXX Sometimes this could be optimized, but these are the
# semantics: we can't depend on the values to be hashable
# or comparable.
olist = list(other)
for x in self:
try:
olist.remove(x)
except ValueError:
return False
assert olist == []
return True

def __ne__(self, other):
result = self.__eq__(other)
if result is not NotImplemented:
result = not result
return result

PEP 3106 -- Revamping(改进) dict.keys(), .values() and .items()的更多相关文章

  1. Python3基础 dict keys+values 循环打印字典中的所有键和值

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  2. 查询set、dict、dict.keys()的速度对比

    查找效率:set>dict>list 单次查询中: list set dict O(n) set做了去重,本质应该一颗红黑树 (猜测,STL就是红黑树),复杂度 O(logn): dict ...

  3. ES2017 keys,values,entries使用

    let {keys, values, entries} = Object; let obj = { a: 1, b: 2, c: 3 }; for (let key of keys(obj)) { c ...

  4. StackExchange.Redis 官方文档(五) Keys, Values and Channels

    原文:StackExchange.Redis 官方文档(五) Keys, Values and Channels Keys, Values and Channels 在使用redis的过程中,要注意到 ...

  5. 37-python基础-python3-字典的常用方法-keys()-values()-items()

    有 3 个字典方法,它们将返回类似列表的值,分别对应于字典的键.值和键-值对:keys().values()和 items(). 这些方法返回的值不是真正的列表,它们不能被修改,没有append()方 ...

  6. ES6扩展——数组的新方法(Array.from、Array.of、Array.fill、Array.includes、keys values entries 、find)

    1.Array.from(objec,回调函数)将一个ArrayLike对象或者Iterable对象(类数组对象)转换成一个数组 1)该类数组对象必须具有length属性,用于指定数组的长度.如果没有 ...

  7. fromkeys() keys() values() items()

    fromkeys() >>> dict1={} >>> dict1.fromkeys((1,2,3))#会自动为没有赋值的值建立none {1: None, 2: ...

  8. keys(),values()和items()

    a={'a':11,'b':'bb','c':321}for x in a.items(): print(x)  # 每条都输出来print("------------")for ...

  9. python中的keys、values、items

    keys()获取字典中所有的键并放入列表 values()获取字典中所有的值并放入列表 items()获取字典中所有的键值对并放入列表 举个例子: 1 a = { 2 "name" ...

随机推荐

  1. Android插件化框架

    1.   dynamic-load-apk/DL动态加载框架 是基于代理的方式实现插件框架,对 App 的表层做了处理,通过在 Manifest 中注册代理组件,当启动插件组件时,首先启动一个代理组件 ...

  2. 用WebService实现两个整数运算

    最近,项目开发中需要用到Web Service.自己在网上搜集资料.自己做了一个小例子,用来加深自己对Web Service理解. 概念:Web Service主要是为了使原来各孤立的站点之间的信息能 ...

  3. BZOJ4456 ZJOI2016旅行者(分治+最短路)

    感觉比较套路,每次在长边中轴线处切一刀,求出切割线上的点对矩形内所有点的单源最短路径,以此更新每个询问,递归处理更小的矩形.因为若起点终点跨过中轴线是肯定要经过的,而不跨过中轴线的则可以选择是否经过中 ...

  4. BZOJ4416 SHOI2013阶乘字符串(状压dp)

    当n大到一定程度(>21)时一定无解,并不会证. 如果要取出一个排列,显然应该让每一位在序列中的位置尽量靠前.于是设f[S]表示存在S子集中这些字母所组成的所有排列的最短前缀的长度,枚举当前排列 ...

  5. Hibernate高级应用

    数据模型与领域模型的关系 领域模型是一个分析模型,它帮助需求分析人员.用户认识现实业务的工具,描述的是业务中设计的试题及其相互之间的关系,它是需求分析的产物.领域模型是需求分析人员与用户交流的有力工具 ...

  6. [bzoj1062] [NOI2008]糖果雨

    Description 有一个美丽的童话:在天空的尽头有一个" 糖果国" ,这里大到摩天大厦,小到小花小草都是用糖果建造而成的.更加神奇的是,天空中飘满了五颜六色的糖果云,很快糖果 ...

  7. [洛谷P3946] ことりのおやつ(小鸟的点心)

    题目大意:最短路,第$i$个点原有积雪$h_i$,极限雪高$l_i$(即雪超过极限雪高就不可以行走),每秒降雪$q$,ことり速度为$1m/s$,若时间大于$g$,则输出$wtnap wa kotori ...

  8. jQuery.getJSON跨域访问的正确使用方式(史上最傻瓜式解释)

    最近花了2天时间完整的看了一遍 jQuery 的API,其中 $.getJSON(url[, data][, callback]) 方法的跨域访问解释真心看的一头雾水,大家可以从这里感受一下: htt ...

  9. linux之scp命令

    linux之cp/scp命令+scp命令详解   名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... dire ...

  10. Kafka自我学习2-Zookeeper cluster

    Test enviroment : zoo1, zoo2, zoo3 cluster 1. Install zookeeper, package in kafka [root@zoo1 ~]# pwd ...