PEP 3106 -- Revamping(改进) dict.keys(), .values() and .items()
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()的更多相关文章
- Python3基础 dict keys+values 循环打印字典中的所有键和值
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- 查询set、dict、dict.keys()的速度对比
查找效率:set>dict>list 单次查询中: list set dict O(n) set做了去重,本质应该一颗红黑树 (猜测,STL就是红黑树),复杂度 O(logn): dict ...
- ES2017 keys,values,entries使用
let {keys, values, entries} = Object; let obj = { a: 1, b: 2, c: 3 }; for (let key of keys(obj)) { c ...
- StackExchange.Redis 官方文档(五) Keys, Values and Channels
原文:StackExchange.Redis 官方文档(五) Keys, Values and Channels Keys, Values and Channels 在使用redis的过程中,要注意到 ...
- 37-python基础-python3-字典的常用方法-keys()-values()-items()
有 3 个字典方法,它们将返回类似列表的值,分别对应于字典的键.值和键-值对:keys().values()和 items(). 这些方法返回的值不是真正的列表,它们不能被修改,没有append()方 ...
- ES6扩展——数组的新方法(Array.from、Array.of、Array.fill、Array.includes、keys values entries 、find)
1.Array.from(objec,回调函数)将一个ArrayLike对象或者Iterable对象(类数组对象)转换成一个数组 1)该类数组对象必须具有length属性,用于指定数组的长度.如果没有 ...
- fromkeys() keys() values() items()
fromkeys() >>> dict1={} >>> dict1.fromkeys((1,2,3))#会自动为没有赋值的值建立none {1: None, 2: ...
- keys(),values()和items()
a={'a':11,'b':'bb','c':321}for x in a.items(): print(x) # 每条都输出来print("------------")for ...
- python中的keys、values、items
keys()获取字典中所有的键并放入列表 values()获取字典中所有的值并放入列表 items()获取字典中所有的键值对并放入列表 举个例子: 1 a = { 2 "name" ...
随机推荐
- 【iOS开发】initWithNibName、initWithCoder、awakeFromNib和 loadNibNamed详解
第一.initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的. 第二.initWithCoder 是一个类在IB中创建但 ...
- 【转载】Linux升级NTPD服务器-编译安装ntp-4.2.8p12与配置
[转载]Linux升级NTPD服务器-编译安装ntp-4.2.8p12与配置 1. 系统与软件版本 1.1 系统版本 rhel6.4(Red Hat Enterprise Linux Server r ...
- SSH面试集锦——不看后悔哦!
1. 谈谈你mvc的理解 MVC是Model-View-Controler的简称.即模型-视图-控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开. MVC中的模型 ...
- HDU 6191 Query on A Tree(可持久化Trie+DFS序)
Query on A Tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Othe ...
- 这次OpenSSL HeartBleed漏洞是怎么一回事呢?
“心脏出血”(Heartbleed)被称为互联网史上最严重的安全漏洞之一,波及了大量常用网站.服务,包括很多人每天都在用的 Gmail 等等,可能导致用户的密码.信用卡轻易泄露.但是我们可能对它还不是 ...
- 兔子与兔子 [Hash]
兔子与兔子 描述 很久很久以前,森林里住着一群兔子.有一天,兔子们想要研究自己的 DNA 序列.我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文字母) ...
- [poj 2274]后缀数组+最长公共子串
题目链接:http://poj.org/problem?id=2774 后缀数组真的太强大了,原本dp是O(nm)的复杂度,在这里只需要O(n+m). 做法:将两个串中间夹一个未出现过的字符接起来,然 ...
- Java实现十进制数转十六进制数
Now~Let's begin our second question~ 如何利用Java语言将十进制数字转换成十六进制数字呢? 我第一次编码出来的效果是酱紫的~ /** * */ package c ...
- offset--BUG
offsetWidth所获取的宽度并不是div的实际宽度,它包括div的width.border等. 在JS函数中,可以通过obj.style.width来获取div的实际宽度,但是这种方式style ...
- TCP(二)
TCP半连接和全连接问题 TCP握手过程详解 如上图所示,关键部分:syns queue(半连接队列)和accept queue(全连接队列) 正常情况下的处理过程如下: 1)当server端收到cl ...