为什么列表没有安全的“获取”像字典一样的方法?
为什么列表没有像字典那样安全的“获取”方法?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
Why doesn't list have a safe "get" method like dictionary?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
最终它可能没有安全的
.get
方法,因为dict
是一个关联集合(值与名称关联),检查键是否存在是低效的。存在(并返回其值)而不引发异常,而避免访问列表元素的异常非常简单(因为 len 方法非常快)。.get
方法允许您查询与名称关联的值,而不是直接访问字典中的第 37 项(这更像是您对列表的要求)。当然,您可以轻松地自己实现:
您甚至可以将其猴子补丁到
__main__
中的__builtins__.list
构造函数上,但这将是一个不太普遍的更改,因为大多数代码都不会不要使用它。如果您只想将其与您自己的代码创建的列表一起使用,您可以简单地子类list
并添加get
方法。Ultimately it probably doesn't have a safe
.get
method because adict
is an associative collection (values are associated with names) where it is inefficient to check if a key is present (and return its value) without throwing an exception, while it is super trivial to avoid exceptions accessing list elements (as thelen
method is very fast). The.get
method allows you to query the value associated with a name, not directly access the 37th item in the dictionary (which would be more like what you're asking of your list).Of course, you can easily implement this yourself:
You could even monkeypatch it onto the
__builtins__.list
constructor in__main__
, but that would be a less pervasive change since most code doesn't use it. If you just wanted to use this with lists created by your own code you could simply subclasslist
and add theget
method.如果您想要第一个元素,例如
my_list.get(0)
我知道这并不完全是您所要求的,但它可能对其他人有帮助。
This works if you want the first element, like
my_list.get(0)
I know it's not exactly what you asked for but it might help others.
可能是因为它对于列表语义来说没有多大意义。但是,您可以通过子类化轻松创建自己的。
Probably because it just didn't make much sense for list semantics. However, you can easily create your own by subclassing.
对于列表来说,像这样使用而不是使用 .get 应该没问题。只是用法不同而已。
Instead of using .get, using like this should be ok for lists. Just a usage difference.
致谢 jose.angel.jimenez、Gus Bus 和 Marek R
对于“oneliner”粉丝......
如果您想要列表的第一个元素,或者如果列表为空时您想要默认值,请尝试:
返回
a
并
返回
default
其他元素的示例...
使用默认后备…
可能更短:
看起来你需要等号前面的逗号,等号和后面的括号。
更通用:
更通用的虚假管理:
使用 Python 3.6.0 进行测试(v3.6.0:41df79263a11,2016 年 12 月 22 日,17:23:13)
Credits to jose.angel.jimenez, Gus Bus and Marek R
For the "oneliner" fans…
If you want the first element of a list or if you want a default value if the list is empty try:
returns
a
and
returns
default
Examples for other elements…
With default fallback…
Possibly shorter:
It looks like you need the comma before the equal sign, the equal sign and the latter parenthesis.
More general:
More general with falsy management:
Tested with
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
您可以做的合理的事情是将列表转换为字典,然后使用 get 方法访问它:
A reasonable thing you can do is to convert the list into a dict and then access it with the get method:
试试这个:
Try this:
所以我对此做了一些更多的研究,结果发现没有任何具体的内容。当我发现 list.index(value) 时,我很兴奋,它返回指定项目的索引,但没有任何东西可以获取特定索引处的值。因此,如果您不想使用我认为非常好的 safe_list_get 解决方案。以下是一些 1 行 if 语句,可以根据情况为您完成工作:
您还可以使用 None 而不是 'No',这更有意义。:
另外,如果您只想获取其中的第一项或最后一项列表,这有效
您也可以将它们放入函数中,但我仍然喜欢 IndexError 异常解决方案。我尝试了
safe_list_get
解决方案的虚拟版本,并使其变得更简单(无默认值):尚未进行基准测试来了解最快的。
So I did some more research into this and it turns out there isn't anything specific for this. I got excited when I found list.index(value), it returns the index of a specified item, but there isn't anything for getting the value at a specific index. So if you don't want to use the safe_list_get solution which I think is pretty good. Here are some 1 liner if statements that can get the job done for you depending on the scenario:
You can also use None instead of 'No', which makes more sense.:
Also if you want to just get the first or last item in the list, this works
You can also make these into functions but I still liked the IndexError exception solution. I experimented with a dummied down version of the
safe_list_get
solution and made it a bit simpler (no default):Haven't benchmarked to see what is fastest.
字典是用来查找的。询问条目是否存在是有意义的。列表通常是迭代的。询问 L[10] 是否存在并不常见,而是询问 L 的长度是否为 11。
Dictionaries are for look ups. It makes sense to ask if an entry exists or not. Lists are usually iterated. It isn't common to ask if L[10] exists but rather if the length of L is 11.
如果你
你可以使用这个:
用法如下:
If you
you can use this:
Usage looks like:
这不是一个极其通用的解决方案,但我遇到过这样的情况:我期望长度为 3 到 5 的列表(带有保护
if
),并且我将值分解为命名变量。我发现了一种简单而简洁的方法:现在
foo
和bar
要么是列表中的第四个和第五个值,要么是None
如果没有那么多的价值。This isn't an extremely general-purpose solution, but I had a case where I expected a list of length 3 to 5 (with a guarding
if
), and I was breaking out the values to named variables. A simple and concise way I found for this involved:Now
foo
andbar
are either the 4th and 5th values in the list, orNone
if there weren't that many values.对于较小的索引值,您可以将
my_list.get(index, default)
实现为
(my_list + [default] * (index + 1))[index]
如果您知道提前索引是什么,那么这可以简化,例如,如果您知道它是 1 那么您可以执行
(my_list + [default, default])[index]
因为列表是前向打包的,这是唯一的失败情况我们需要担心的是超出了列表的末尾。这种方法用足够的默认值填充列表的末尾,以保证索引被覆盖。
For small index values you can implement
my_list.get(index, default)
as
(my_list + [default] * (index + 1))[index]
If you know in advance what index is then this can be simplified, for example if you knew it was 1 then you could do
(my_list + [default, default])[index]
Because lists are forward packed the only fail case we need to worry about is running off the end of the list. This approach pads the end of the list with enough defaults to guarantee that index is covered.
您的用例基本上仅与处理固定长度的数组和矩阵时相关,以便您事先知道它们有多长。在这种情况下,您通常还会在手动用 None 或 0 填充它们之前创建它们,因此实际上您将使用的任何索引都已经存在。
你可以这样说:我经常需要字典上的 .get() 。作为一名全职程序员十年之后,我认为我不再需要将它列入清单。 :)
Your usecase is basically only relevant for when doing arrays and matrixes of a fixed length, so that you know how long they are before hand. In that case you typically also create them before hand filling them up with None or 0, so that in fact any index you will use already exists.
You could say this: I need .get() on dictionaries quite often. After ten years as a full time programmer I don't think I have ever needed it on a list. :)