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

Python 2.7中 ,我可以将字典作为列表:

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

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

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

所以,我必须这样做才能得到一个清单:

 newlist = list() for i in newdict.keys(): newlist.append(i) 

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

尝试list(newdict.keys())

这将把dict_keys对象转换成一个列表。

另一方面,你应该问自己是否重要。 Pythonic的编码方式是假设鸭子打字( 如果它看起来像一只鸭子,它像一只鸭子,它是一只鸭子 )。 dict_keys对象将用于大多数目的的列表。 例如:

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

很明显,插入操作符可能无法工作,但是对于字典键列表来说没有多大意义。

在“duck typing”定义上有一点点dict.keys()dict.keys()返回一个可迭代的对象,而不是一个类似列表的对象。 它将工作在任何一个迭代将工作 – 没有任何地方的清单。 一个列表也是一个可迭代的,但一个迭代不是一个列表(或序列…)

在实际使用情况下,在字典中最常用的关键是遍历它们,所以这是有道理的。 如果你确实需要它们,你可以调用list()

对于zip()非常类似 – 在大多数情况下,迭代通过 – 为什么创build一个新的元组列表只是为了遍历它,然后再把它扔掉?

这是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']] 

list(dict)可以在Python 2和Python 3中使用,在字典中提供一个简单的键列表。 keys()是没有必要的。 (:

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

在Python 3.5中引入了新的解包概括,现在您可以轻松完成:

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

使用*解包可以与任何可迭代的对象一起使用,并且由于字典在迭代时产生密钥,因此可以使用它轻松创build列表。

它相当于list(newdict) ,区别在于它更快(至less对于小字典),因为没有实际的函数调用:

 %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 

与更大的字典,速度几乎相同。


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

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

小心在tuple情况下的尾随逗号!

你也可以使用列表理解

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

转换为列表而不使用keys方法使其更具可读性:

 list(newdict) 

在循环字典时,不需要keys()

 for key in newdict: print key 

除非在循环中修改它,否则需要事先创build一个键列表:

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

在Python 2中,使用keys()会有一个边际的性能增益

除了在这个页面上提到的方法之外,你可以使用operatorget模块中的itemgetter

 >>> from operator import itemgetter >>> list(map(itemgetter(0), dd.items())) [1, 2, 3] 

你也可以做一个tuple(dict)set(dict)

 >>> list(set(newdict)) [1, 2, 3] >>> list(tuple(newdict)) [1, 2, 3] 

此外,列表理解似乎不工作:

 >>> parsed_results.keys() dict_keys(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes']) >>> things2plot = [key.split(', ') for key in parsed_results.keys()] >>> things2plot ['Sounder V Depth', 'F'] >>> for key in parsed_results.keys(): ... print(key.split(', ')) ... ['Sounder V Depth', 'F'] ['Vessel Latitude', 'Degrees-Minutes'] 

就我个人而言,我认为这是对鸭子打字的“违反”,因此是一个“错误”。 但是我认为现在还有其他人注意到了这一点,所以如果没有确定的话,就必须被认为是一个“特征”,但是我不能为了我的生活而明白为什么。

对Chris的补充说明:

好了,克里斯,那么至less应该更好的误用检测和通知(“你似乎不想要一个迭代器在这里,你是否期待一个列表?试试列表(dict.keys())…”)会更像我已经知道并喜爱的有用的Python。 :/(我要求你提供数据来支持你声明迭代器的function是dict.keys的“更常见”的用例,但是你可能会提供它。);-)到目前为止因为我的列表理解的例子不工作(对我来说),它是从PyCharmdebugging器命令行剪切和粘贴的,所以也许这个问题是一个错误。 (我今天已经遇到过另外一个“bug”了,所以根本不会让我感到吃惊。)谢谢!