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

656 python dictionary list python-2.x python-3.x

Python 2.7中,我可以将字典,项目作为列表获取:

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

现在,在Python> = 3.3中,我得到这样的东西:

>>> newdict.keys()
dict_keys([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

所以,我必须这样做以获得一个列表:

newlist = list()
for i in newdict.keys():
    newlist.append(i)
Run Code Online (Sandbox Code Playgroud)

我想知道,有没有更好的方法来返回Python 3中的列表?

Chr*_*is 828

试试list(newdict.keys()).

这会将dict_keys对象转换为列表.

另一方面,你应该问问自己是否重要.Pythonic编码方式是假设鸭子打字(如果它看起来像鸭子,它像鸭子一样嘎嘎叫,它是一只鸭子).该dict_keys对象会像在大多数情况列表.例如:

for key in newdict.keys():
  print(key)
Run Code Online (Sandbox Code Playgroud)

显然,插入操作符可能不起作用,但无论如何这对字典键列表没有多大意义.

  • `list(newdict)`也有效(至少在python 3.4中).有没有理由使用`.keys()`方法? (49认同)
  • newdict.keys()不支持索引 (38认同)
  • 注意:在调试器`pdb>列表(newdict.keys())中失败,因为它与pdb的同名命令冲突.使用`pdb>!list(newdict.keys())`来转义pdb命令. (38认同)
  • @ naught101是的,`.keys()`对于发生的事情更清楚了. (17认同)
  • random.choice(newdict.keys())也不起作用! (3认同)
  • 请注意,如果您使用 list(newdict.keys()) ,由于散列顺序,这些键不在您放置它们的顺序中! (3认同)

Jim*_*ard 218

Python> = 3.5替代方法:解压缩到列表文字中 [*newdict]

Python 3.5引入了新的解包通用化(PEP 448),现在您可以轻松地执行以下操作:

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

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

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

*iterable语法类似于做list(iterable)其行为最初记录在呼叫部分 Python的参考手册.使用PEP 448时,对*iterable可能出现的位置的限制被放宽,允许它也被放置在列表,集合和元组文字中,表达式列表上的参考手册也被更新以说明这一点.


虽然相当于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
Run Code Online (Sandbox Code Playgroud)

对于较大的词典,速度几乎相同(迭代大型集合的开销胜过函数调用的小成本).


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

>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}
Run Code Online (Sandbox Code Playgroud)

谨防元组中的尾随逗号!

  • 今天学到了两件事:1.我可以将 `list(some_dict.keys())` 缩写为 `[*some_dict]`,2. 表达方式“code Golfer”(以及 2a.“code Golfer”的含义 - 在谷歌搜索后)它) (7认同)
  • `*newdict` - 这绝对是代码高尔夫球手的答案;P。另外:*老实说,这不是您真正应该担心的事情* - 如果是的话,**不要使用python**。 (3认同)
  • @MYounas 这种语法已经有很长一段时间了,即使在 Python 2 中也是如此。在函数调用中,您可以执行 `def foo(*args): print(args)` 后跟 `foo(*{1:0, 2:0 })` 并打印结果 `(1, 2)`。此行为在参考手册的 [Calls](https://docs.python.org/3/reference/expressions.html#calls) 部分中指定。带有 PEP 448 的 Python 3.5 刚刚放宽了这些出现位置的限制,允许现在使用 `[*{1:0, 2:0}]`。无论哪种方式,我都会编辑我的答案并包括这些。 (2认同)

Seb*_*Seb 36

list(newdict)适用于Python 2和Python 3,提供了一个简单的键列表newdict.keys()没有必要.(:


小智 23

关于"duck typing"定义的一点点 - dict.keys()返回一个可迭代对象,而不是类似列表的对象.它可以在迭代工作的任何地方工作 - 而不是列表的任何位置.列表也是可迭代的,但是iterable不是列表(或序列......)

在实际使用案例中,最常见的与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']]
Run Code Online (Sandbox Code Playgroud)

  • 你甚至不需要使用 `.keys()`;字典对象*本身*是可迭代的,并在迭代时生成键:`[key.split(", ") for key in d]`。 (3认同)

未来陆*_*投资人 18

您还可以使用列表理解:

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

  • 只需使用`list(newdict)`。这里不需要列表理解。 (2认同)

Dev*_*vil 14

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


使用 inbuild list() 函数

#Devil
newdict = {1:0, 2:0, 3:0}
key_list = list(newdict)
print(key_list) 
#[1, 2, 3] 
Run Code Online (Sandbox Code Playgroud)


Cas*_*Cas 8

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

list(newdict)
Run Code Online (Sandbox Code Playgroud)

并且,当循环通过词典时,不需要keys():

for key in newdict:
    print key
Run Code Online (Sandbox Code Playgroud)

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

for key in list(newdict):
    del newdict[key]
Run Code Online (Sandbox Code Playgroud)

在Python 2上,使用了一个边际性能增益keys().


Rah*_*hul 7

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

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

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

方法 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']
Run Code Online (Sandbox Code Playgroud)


cs9*_*s95 6

如果您需要单独存储密钥,那么此解决方案使用扩展的可迭代拆包(python3.x +),与迄今提供的所有其他解决方案相比,其键入所需的内容更少。

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

k
# [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
            ???????????????????????????????????????????????????????????
            ? k = list(d)   ?   9 characters (excluding whitespace)   ?
            ???????????????????????????????????????????????????????????
            ? k = [*d]      ?   6 characters                          ?
            ???????????????????????????????????????????????????????????
            ? *k, = d       ?   5 characters                          ?
            ???????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

  • @endolith 也许是 `keys, vals = zip(*d.items())` (尽管这给出了两个元组,足够接近)。我不知道还有比这更短的表达方式。 (2认同)

Giu*_*pox 6

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

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

注意:该解决方案不应该在开发环境中使用;*我在这里展示它只是因为我认为从运算符优于字典的角度来看它非常有趣。另外,我不确定这是否是已记录的功能,并且其行为可能会在以后的版本中发生变化:)