首页 文章

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

提问于
浏览
381

在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中的列表?

10 回答

  • 21

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

    list(newdict)
    

    并且,当循环遍历词典时,不需要 keys()

    for key in newdict:
        print key
    

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

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

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

  • 0

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

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

    就个人而言,我认为这是对鸭子打字的“违反”,因此也是“错误” . 但我认为其他人现在必须注意到这一点,因此如果它没有被修复,必须被视为“特征”,但我不能为我的生活看到原因 .

    答复克里斯的补遗:

    好吧,克里斯,那么至少更好地滥用检测和通知(“你似乎不想在这里使用迭代器;你期待一个列表吗?尝试列表(dict.keys())......”)会更像我非常熟悉和喜爱的Python . :/(我要求你提供数据来支持你声称迭代器功能是dict.keys的“更常见”的用例,但是你可能能够提供它 . );-)目前为止由于我的列表理解示例不起作用(对我来说),它是从PyCharm调试器命令行剪切并粘贴的,所以可能问题是这个中的错误 . (我今天已经遇到过另一个“错误”,所以这根本不会让我感到惊讶 . )谢谢!

  • 19

    你也可以使用 list comprehension

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

    试试 list(newdict.keys()) .

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

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

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

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

  • 490

    在"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']]
    
  • 109

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

  • 7

    Python >= 3.5 alternative: unpack into a list literal [*newdict]

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

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

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

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

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

    虽然相当于 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}
    

    小心元组中的尾随逗号!

  • 6

    另一个简单的选择是使用列表理解:

    [key for key in dct.keys()]
    
  • 2

    除了本页提到的方法之外,您还可以使用操作员模块中的 itemgetter

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

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

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

相关问题