ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Python 中将字典键作为列表返回?

使用 Python 2.7,我可以将字典 keysvaluesitems 作为 list

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

使用 Python >= 3.3,我得到:

>>> newdict.keys()
dict_keys([1, 2, 3])

如何使用 Python 3 获得简单的 list 键?

我是 Python 新手,对我来说,这种无用的新数据类型的泛滥似乎是 Python 最糟糕的方面之一。这个 dict_keys 数据类型有什么用?为什么不是清单?

M
Mateen Ulhaq

这会将 dict_keys 对象转换为 list

list(newdict.keys())

另一方面,你应该问问自己这是否重要。假设 duck typing 是 Pythonic 的——如果它看起来像一只鸭子,它叫起来像一只鸭子,那么它就是一只鸭子dict_keys 对象可以像 list 一样被 iterated 覆盖。例如:

for key in newdict.keys():
    print(key)

请注意,dict_keys 不支持插入 newdict[k] = v,尽管您可能不需要它。


newdict.keys() 不支持索引
list(newdict) 也有效(至少在 python 3.4 中)。有任何理由使用 .keys() 方法吗?
注意:在调试器中 pdb> list(newdict.keys()) 失败,因为它与 pdb 的同名命令冲突。使用 pdb> !list(newdict.keys()) 转义 pdb 命令。
@naught101 是的,.keys() 对发生的事情更加清楚。
请注意,如果您使用 list(newdict.keys()) 由于散列顺序,键不在您放置它们的顺序!
D
Dimitris Fasarakis Hilliard

Python >= 3.5 替代方案:解压成列表文字 [*newdict]

Python 3.5 引入了新的 unpacking generalizations (PEP 448),您现在可以轻松地执行以下操作:

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]

使用 * 解包适用于可迭代的 any 对象,并且由于字典在迭代时返回其键,因此您可以通过在列表文字中使用它来轻松创建列表。

添加 .keys()[*newdict.keys()] 可能有助于使您的意图更加明确,尽管它会花费您函数查找和调用。 (老实说,这不是您应该真正担心的事情)。

*iterable 语法类似于 list(iterable),其行为最初记录在 Python 参考手册的 Calls section 中。在 PEP 448 中,放宽了对 *iterable 出现位置的限制,允许它也被放置在列表、集合和元组文字中,Expression lists 的参考手册也进行了更新以说明这一点。

虽然等同于 list(newdict) ,但它更快(至少对于小型字典),因为实际上没有执行任何函数调用:

%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop

%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop

%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop

使用更大的字典,速度几乎相同(迭代大型集合的开销胜过函数调用的小成本)。

以类似的方式,您可以创建元组和字典键集:

>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}

当心元组案例中的尾随逗号!


很好的解释,但是请您参考任何描述这种“* newdict”类型语法的链接,我的意思是如何以及为什么返回字典中的键只是为了理解。谢谢
@MYounas 即使在 Python 2 中,该语法也已经存在了很长一段时间。在函数调用中,您可以执行 def foo(*args): print(args) 后跟 foo(*{1:0, 2:0}) 并打印结果 (1, 2)。此行为在参考手册的 Calls 部分中指定。带有 PEP 448 的 Python 3.5 刚刚放宽了对这些可以出现的位置的限制,允许现在使用 [*{1:0, 2:0}]。无论哪种方式,我都会编辑我的答案并包括这些。
*newdict - 这绝对是代码高尔夫球手的答案;P。另外:老实说,这不是你真正应该担心的事情 - 如果你担心,不要使用 python
今天学到了两件事:1. 我可以将 list(some_dict.keys()) 缩短为 [*some_dict],2. 表达“代码高尔夫球手”(以及 2a。“代码高尔夫球手”的含义 - 谷歌搜索后)
H
Henry Ecker

list(newdict) 适用于 Python 2 和 Python 3,提供了 newdict 中键的简单列表。 keys() 不是必需的。


c
cs95

您还可以使用列表推导:

>>> newdict = {1:0, 2:0, 3:0}
>>> [k  for  k in  newdict.keys()]
[1, 2, 3]

或者,更短的,

>>> [k  for  k in  newdict]
[1, 2, 3]

注意:3.7 以下的版本不保证顺序(顺序仍然只是 CPython 3.6 的实现细节)。


只需使用 list(newdict)。这里不需要列表理解。
C
Chris Barker

“鸭子类型”定义有点偏离——dict.keys() 返回一个可迭代对象,而不是类似列表的对象。它可以在任何可迭代的地方工作——而不是列表可以工作的任何地方。列表也是可迭代的,但可迭代不是列表(或序列...)

在实际用例中,与 dict 中的键有关的最常见的事情是遍历它们,所以这是有道理的。如果您确实需要它们作为列表,您可以调用 list()

zip() 非常相似——在绝大多数情况下,它是迭代的——为什么要创建一个全新的元组列表来迭代它,然后再把它扔掉?

这是 python 使用更多迭代器(和生成器)而不是到处复制列表的大趋势的一部分。

但是,dict.keys() 应该与理解一起使用 - 仔细检查拼写错误或其他东西......它对我来说很好:

>>> d = dict(zip(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes'], [None, None]))
>>> [key.split(", ") for key in d.keys()]
[['Sounder V Depth', 'F'], ['Vessel Latitude', 'Degrees-Minutes']]

您甚至不需要使用 .keys();字典对象是自身可迭代的,并在迭代时产生键:[key.split(", ") for key in d]
T
Tomerikoo

如果您需要单独存储密钥,这是一个使用 Extended Iterable Unpacking (Python3.x+) 的解决方案,它比迄今为止提出的所有其他解决方案需要更少的输入:

newdict = {1: 0, 2: 0, 3: 0}
*k, = newdict

k
# [1, 2, 3]

操作编号字符数 k = list(d) 9 个字符(不包括空格) k = [*d] 6 个字符 *k, = d 5 个字符


我要指出的唯一小警告是 k 始终是此处的列表。如果用户想要一个元组或来自键的集合,他们将需要回退到其他选项。
一个更值得注意的事实是,作为一个语句,*k, = d 对它可以出现的位置有限制(但请参阅并可能更新这个答案,PEP 572 - 赋值表达式 atm 但是可能有一天!)
如果您想要列表的键和值怎么办?
@endolith 也许是 keys, vals = zip(*d.items()) (尽管这给出了两个元组,足够接近)。我不知道有比这更短的表达方式。
D
Dimitris Fasarakis Hilliard

在不使用 keys 方法的情况下转换为列表使其更具可读性:

list(newdict)

并且,在遍历字典时,不需要 keys()

for key in newdict:
    print key

除非您在循环中修改它,这需要预先创建的键列表:

for key in list(newdict):
    del newdict[key]

在 Python 2 上,使用 keys() 可以获得边际性能提升。


R
Rahul

我可以想到两种从字典中提取键的方法。

方法 1: - 使用 .keys() 方法获取密钥,然后将其转换为列表。

some_dict = {1: 'one', 2: 'two', 3: 'three'}
list_of_keys = list(some_dict.keys())
print(list_of_keys)
-->[1,2,3]

方法2: - 创建一个空列表,然后通过循环将键附加到列表中。您也可以使用此循环获取值(使用 .keys() 仅用于键,使用 .items() 用于键和值提取)

list_of_keys = []
list_of_values = []
for key,val in some_dict.items():
    list_of_keys.append(key)
    list_of_values.append(val)

print(list_of_keys)
-->[1,2,3]

print(list_of_values)
-->['one','two','three']

D
Devil

是的,在 python3.X 中有一个更好和最简单的方法来做到这一点

使用 inbuild list() 函数

#Devil
newdict = {1:0, 2:0, 3:0}
key_list = list(newdict)
print(key_list) 
#[1, 2, 3] 

这与@Seb 的回答有何不同?
@jochen:代码和简单解释:)
m
mkrieger1

除了执行此操作的经典(可能更正确)方式(some_dict.keys())之外,还有一种更“酷”且肯定更有趣的方式来执行此操作:

some_dict = { "foo": "bar", "cool": "python!" }
print( [*some_dict] == ["foo", "cool"] )         # True  

注意:此解决方案不应在开发环境中使用;我在这里展示它只是因为我认为从 *-operator-over-dictionary 的角度来看它非常有趣。另外,我不确定这是否是一个记录的功能,它的行为可能会在以后的版本中改变:)


2
2 revs

这是在一行代码中获取密钥列表的最佳方式

dict_variable = {1:"a",2:"b",3:"c"}  
[key_val for key_val in dict_variable.keys()]

我想你的意思是[key_val for key_val in dict_variable.keys()]