繁体   English   中英

如何在变量中提取字典单键值对

[英]How to extract dictionary single key-value pair in variables

我的字典中只有一个键值对。 我想将键分配给一个变量,并将其值分配给另一个变量。 我已经尝试过以下方法,但我得到了同样的错误。

>>> d = {"a": 1}

>>> d.items()
[('a', 1)]

>>> (k, v) = d.items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack

>>> (k, v) = list(d.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 1 value to unpack

我知道我们可以一个一个地提取键和值,或者通过 for 循环和iteritems()来提取,但是没有一种简单的方法可以在一个语句中分配两者吗?

添加另一个级别,带有一个元组(只是逗号):

(k, v), = d.items()

或列表:

[(k, v)] = d.items()

或挑出第一个元素:

k, v = d.items()[0]

前两个具有额外的优势,如果您的字典有多个键,它们会抛出异常,并且两者都适用于 Python 3,而后者必须拼写为k, v = next(iter(d.items()))工作。

演示:

>>> d = {'foo': 'bar'}
>>> (k, v), = d.items()
>>> k, v
('foo', 'bar')
>>> [(k, v)] = d.items()
>>> k, v
('foo', 'bar')
>>> k, v = d.items()[0]
>>> k, v
('foo', 'bar')
>>> k, v = next(iter(d.items()))  # Python 2 & 3 compatible
>>> k, v
('foo', 'bar')

items()返回一个元组列表,因此:

(k,v) = d.items()[0]
>>> d = {"a":1}
>>> [(k, v)] = d.items()
>>> k
'a'
>>> v
1

或使用nextiter

>>> k, v = next(iter(d.items()))
>>> k
'a'
>>> v
1
>>>
d = {"a": 1}

你可以做

k, v = d.keys()[0], d.values()[0]

d.keys()实际上将返回所有键的列表,而d.values()返回所有值的列表,因为您在d中有一个键:值对,您将访问键和值列表中的第一个元素

在 Python 3 中:

简短的回答:

[(k, v)] = d.items()

或者:

(k, v) = list(d.items())[0]

或者:

(k, v), = d.items()

长答案:

d.items() ,基本上(但实际上不是)给你一个带有元组的列表,它有 2 个值,打印时看起来像这样:

dict_items([('a', 1)])

您可以通过使用list()包装将其转换为实际列表,这将产生以下值:

[('a', 1)]

使用.popitem()方法。

k, v = d.popitem()

如果字典中有很多项,这是最好的,因为它实际上并没有创建一个列表,而是只产生一个键值对。

k, v = next(d.iteritems())

当然,如果您的字典中有不止一项,则无法知道您会删除哪一项。

你有一个清单。 您必须索引列表才能访问元素。

(k,v) = d.items()[0]

如果您只想要字典键而不关心值,请注意(key, ), = foo.items()不起作用。 您确实需要将该值分配给变量。

所以你需要(key, _), = foo.items()

Python 3.7.2 中的插图:

>>> foo = {'a': 1}
>>> (key, _), = foo.items()
>>> key
'a'
>>> (key, ), = foo.items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 1)
key = list(foo.keys())[0]
value = foo[key]

在 Python 3 中

最简单(最简洁)的答案可能是:

k, = d.keys()

例子:

>>> d = {"a": 1}
>>> k, = d.keys()
>>> k
'a'

同样的想法也可以应用于values()items()

>>> v, = d.values()
>>> v
1

>>> (k, v), = d.items()
>>> k
'a'
>>> v
1

您将获得上述相同的好处,即ValueError如果您的dict有超过 1 个键:

>>> d = {"a": 1, "b": 2}
>>> k, = d.keys()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 1)

额外细节

对于k, = d.keys()中的尾随逗号 ( , ) 也存在一些混淆。 尽管它是不请自来的(并且离题),但这是我可以解释它的最佳方式。

尾随逗号只是“表达式列表”赋值(又名“元组赋值”)的符号。 没有它,您将只分配一个dict_keys对象,而不是同一对象包含的第一个(也是唯一一个)值的值:

>>> k = d.keys()
>>> k
dict_keys(['a'])

具体细节可以在The Python Language Reference, 7. Simple statements中找到(尽管该文档有点过于密集,我的口味)。

基本上,只要保留一对一的赋值,就可以将多个变量解包(或赋值)给一行中的多个变量(除非使用星号赋值* )。

>>> (a, b, c) = (1, 2, 3)
>>> a
1

并且因为括号是可选的,所以以下是等价的:

>>> a, b, c = 1, 2, 3
>>> b
2

因为(a, b, c) = (1, 2, 3) <==> a, b, c = 1, 2, 3 ,相同的列表赋值表达式可以用于单个项目,除了具有单个项目的元组必须有一个尾随逗号

没有它,括号将作为表达式计算,并分配包含的结果值:

>>> t = (1)
>>> type(t)
<class 'int'>
>>> t
1

虽然一开始这看起来很奇怪,但如果你查看一个包含单个项目的tuplerepr() ,你会发现它始终用尾随逗号表示:

>>> tuple([1])
(1,)

>>> t = ('a',)
>>> type(t)
<class 'tuple'>
>>> t
('a',)

话虽如此,从语法上讲,您可以在技术上使用带有(或不带有)可选括号的单个项目执行元组赋值,只要您包含尾随逗号:

# weird, but okay...
>>> (a,) = (1,)
>>> a
1

# technically, sure... but please don't do this.
>>> a, = 1,
>>> a
1

事实上,使用尾随逗号分配任何值都会被评估为一个元组:

# assignment with a trailing comma (without parentheses)
>>> t = 1,
>>> type(t)
<class 'tuple'>
>>> t
(1,)

虽然这种语法看起来很奇怪,并且不常用,但它确实会不时弹出来解决不常见的问题(比如这个)。

如果有帮助,您始终可以包含可选括号,因为“ 显式优于隐式。 ”:

# original example
>>> d = {"a": 1}

# get (only) key
>>> (k,) = d.keys()
>>> k
'a'

# get (only) value
>>> (v,) = d.values()
>>> v
1

# get (only) key and value
>>> ((k, v),) = d.items()
>>> k
'a'
>>> v
1

希望有帮助。

TL;博士

问:你如何从带有单个项目的dict中 [解包] [key||value]?

A: 创造性地,用甜蜜的句法糖,宝贝!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM