从Python中的单元素列表中仅获取元素?


80

当已知Python列表始终包含单个项目时,除了以下方式之外,还有其他方法可以访问它:

mylist[0]

您可能会问,“为什么要这么做?”。仅凭好奇心。似乎有这样做的另一种方式在Python。


5
可能有其他选择,但是通常只有一种明显的方法可以实现-在这种情况下,您似乎已经找到了它。
ekhumoro

如果它始终包含单个项目,那么也许list不是最佳数据类型?
大卫·泽门斯

12
@ekhumoro:实际上,我偏爱序列拆包方法,因为它验证了序列仅包含一个元素的假设。mylist[0]如果您至少拥有一个元素,则成功,但是如果您实际拥有30个元素,则不会抱怨。singleitem, = mylist验证您只有一个元素,没有更多,不少。
ShadowRanger 2015年

1
@ShadowRanger。问题明确地是关于访问列表中已知包含单个项目的唯一元素。
ekhumoro

6
@ekhumoro:没意见。我只是喜欢防御性地进行编程,所以不会默默地违反要求(确保失败,但会大声失败,这比细微的不当行为容易识别和修复)。如果我每次都能在生产代码中发现某些“已知的”行为都是完全错误的话,那么……我可能不会有钱,但是我可以带家人去一个非常好的环境晚餐。
ShadowRanger 2015年

Answers:


119

序列拆包:

singleitem, = mylist
# Identical in behavior (byte code produced is the same),
# but arguably more readable since a lone trailing comma could be missed:
[singleitem] = mylist

明确使用迭代器协议:

singleitem = next(iter(mylist))

破坏性流行音乐:

singleitem = mylist.pop()

负指数:

singleitem = mylist[-1]

通过单次迭代进行设置for(因为循环终止时,循环变量的最后一个值仍然可用):

for singleitem in mylist: break

还有很多其他的东西(结合或改变以上内容,或者依赖于隐式迭代),但是您可以理解。


6
由于精神错乱猖,不值得包含在主要答案中:参数解压缩到单个参数函数(作为匿名lambda完成,返回最大愚蠢值):singleitem = (lambda x: x)(*mylist)
ShadowRanger 2015年

6
第一个是唯一的,如果列表包含多个元素,它也会引发。
Neil G

7
第一个也可以写成[singleitem] = mylist
Carsten S 2015年

@NeilG:可悲的是,它并不是完全独特的。注释中的“猖in疯狂”版本也可以做到这一点(通过列表语法进行解压缩也可以,尽管实际上与第一个示例行为方式相同)。我现在有点脏。
ShadowRanger 2015年

1
@CarstenS:通常,我不喜欢使用[]序列解压(for [i, x] in enumerate(iterable):让我胆怯),但是是的,在解压缩单个值的情况下,尾随逗号很容易被忽略,出于可读性原因,使用方括号是合理的。我已将其添加到答案中。谢谢!
ShadowRanger 2015年

20

我将添加一个more_itertools 库,该工具可从迭代器返回一项。

from more_itertools import one


iterable = ["foo"]
one(iterable)
# "foo"

此外,more_itertools.one如果iterable为空或具有多个项目,则会引发错误。

iterable = []
one(iterable)
# ValueError: not enough values to unpack (expected 1, got 0)

iterable = ["foo", "bar"]
one(iterable)
# ValueError: too many values to unpack (expected 1)

more_itertools 是第三方软件包 > pip install more-itertools

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.