【问题标题】:What's a more Pythonic way of grabbing N items from a dictionary?从字典中获取 N 个项目的更 Pythonic 的方式是什么?
【发布时间】:2022-07-05 13:53:58
【问题描述】:

在 Python 中,假设我想从字典中获取 N 个任意项目——例如,打印它们,检查一些项目。我不在乎我得到了哪些物品。我不想把字典变成一个列表(就像我看到的一些代码一样);这似乎是一种浪费。我可以使用以下代码(其中 N = 5)来完成,但似乎必须有一种更 Pythonic 的方式:

count = 0
for item in my_dict.items():
    if count >= 5:
        break
    print(item)
    count += 1

提前致谢!

【问题讨论】:

  • 那么这段代码有什么问题呢?这实际上看起来已经是一种很好的 Pythonic 方式了。
  • 我猜这是使用计数器,这似乎更典型的 C/C++,至少从我的理解来看。但我是 Python 新手,我知道什么?我只是觉得可能有更惯用的东西。

标签: python dictionary


【解决方案1】:

您可以使用itertools.islice 对任何可迭代对象(不仅是列表)进行切片:

>>> import itertools
>>> my_dict = {i: i for i in range(10)}
>>> list(itertools.islice(my_dict.items(), 5))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

【讨论】:

  • 对于我的用例,我会遍历切片:for item in itertools.islice(my_dict.items(), 5): print(item)
  • 这是有道理的。我使用list() 来打印生成的生成器的表示,一般不需要。
【解决方案2】:

我可能会使用ziprange

>>> my_dict = {i: i for i in range(10)}
>>> for _, item in zip(range(5), my_dict.items()):
...     print(item)
...
(0, 0)
(1, 1)
(2, 2)
(3, 3)
(4, 4)

这里range 的唯一目的是提供一个可导致zip 在5 次迭代后停止的可迭代对象。

【讨论】:

  • 有趣!作为初学者/中级学习者,我有点难以阅读。
  • @bhagerty 诀窍在于zip 将结果截断为最短迭代器的长度。这就是为什么此解决方案根据 my_dict 的大小返回 5 个或更少元素的原因。
  • 感谢@Selcuk!有道理为什么它有效。尽管如此,由于“可读性很重要”(PEP 20),我想指出我发现它很难阅读。我认为itertools 解决方案更具可读性。
【解决方案3】:

您可以稍微修改一下:

for count, item in enumerate(dict.items()):
    if count >= 5:
        break
    print(item)

注意:在这种情况下,当您遍历 .items() 时,您将获得一个键/值对,可以在迭代时对其进行解包:

for count, (key, value) in enumerate(dict.items()):
    if count >= 5:
        break
    print(f"{key=} {value=})

如果你只想要键,你可以遍历字典。

for count, key in enumerate(dict):
    if count >= 5:
        break
    print(f"{key=})

如果你只想要值:

for count, value in enumerate(dict.values()):
    if count >= 5:
        break
    print(f"{value=})

最后一点:使用dict 作为变量名会覆盖内置的dict 并使其在您的代码中不可用。

【讨论】:

  • 绝对是一个改进,enumerate 更 Pythonic。不过,仍然不确定是否使用“计数”。另外,感谢关​​于dict 的观点。我将问题修改为不使用它(我在实践中没有使用它;这只是概括我的问题的草率尝试)。
【解决方案4】:

通常,我想使用切片表示法来执行此操作,但 dict.items() 返回一个 迭代器,它不是可切片的。

您有两个主要选择:

  1. 让它适用于切片符号:
x = {'a':1, 'b':2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
for item, index in list(x.items())[:5]:
  print(item)
  1. 使用适用于迭代器的东西。在这种情况下,内置(并且非常流行)的 itertools 包:
import itertools
x = {'a':1, 'b':2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
for item in itertools.islice(x.items(), 5):
  print(item)

【讨论】:

  • 第一种方法比 O.P. 的代码更糟糕,因为它创建了一个不必要的列表来复制整个字典。并且“项目,索引”是字典中键和值的错误变量名。 islice 很好,但在之前的答案中已经提到过。
  • 谢谢!使用列表的解决方案 1 是我在我的问题中看到并试图排除的。我很确定将整个字典转换为列表,这样我就可以从列表中获取一些项目。但解决方案 2 正是我想要的。
  • 实际上,我现在意识到解决方案 2 不太有效,因为它只对键进行切片,而我想要键和值。我需要for item in itertools.islice(my_dict.items(), 5): 等。
猜你喜欢
  • 1970-01-01
  • 2021-08-03
  • 2010-10-09
  • 2012-04-16
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-03
相关资源
最近更新 更多