如何从未知数量的字典列表中返回键值字典对?

时间:2021-01-12 06:12:24

标签: python dictionary

我有作为单个字典返回的数据,例如:

{'key': 'RIDE', '3': 27.3531}

或作为未知数量的字典列表(即最多可以是 20 个字典列表或 2 个,如图所示),例如:

[{'key': 'GH', '3': 154.24}, {'key': 'RIDE', '3': 27.34}]

我想编写一段代码来遍历字典列表并返回每个字典中的所有键值对。

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

要对此进行实验,我们首先必须编写一些带有虚拟数据提供程序的代码,该数据提供程序返回字典或字典列表:

import random

def doSomething():
    if random.random() <= 0.5:
        return {'key': 'RIDE', '3': 27.3531}
    else:
        return [{'key': 'GH', '3': 154.24}, {'key': 'RIDE', '3': 27.34}]
#

现在我们遇到了您描述的这种情况:您有时会收到字典,有时会收到字典列表。

现在:如何处理这种情况?这不是太难:

x = doSomething()
if isinstance(x, dict):
    x = [ x ]

for item in x:
    print(item)

所以我们知道我们要么接收一个字典,要么接收一个字典列表,我们可以测试返回的值是哪种类型。由于始终处理列表更方便,因此上面的示例首先将返回的字典转换为列表,然后再进行任何其他数据处理。

所以这是通过“更正错误”来完成的:错误在于您的数据提供者并不总是返回相同类型的数据。所以每当我们收到字典时,我们首先将字典打包成一个列表。只有在此之后,我们才开始我们首先想要进行的数据处理。这里的处理只是打印字典,但当然您可以遍历键和值以及您提到的或进行任何您认为合适的数据处理。

但是:拥有某种函数或任何类型的子系统来返回不同类型的数据并不是一个好主意。如您所见,这会强制在调用方一侧实现额外的逻辑。此外,如果我们想编写规范(并且我们想在/为更复杂的程序编写规范),它会使事情复杂化。

示例:

import typing
import random

def doSomething() -> typing.Union[dict,typing.List[dict]]:
    if random.random() <= 0.5:
        return {'key': 'RIDE', '3': 27.3531}
    else:
        return [{'key': 'GH', '3': 154.24}, {'key': 'RIDE', '3': 27.34}]
#

这里的规范是使用 typing 功能的正式规范。所以这个关于返回类型的信息是以正式的方式指定的。尽管在正常情况下 Python 通常不会直接评估此信息,但此规范为任何程序员提供了有关返回类型的知识。

当然,我们也可以通过编写某种文本文档以非正式方式编写这样的规范,但这没有任何区别:通常,具有不同类型的返回值会使事情变得不必要地复杂化。你可以这样做——在情况下这是有意义的——但总的来说,最好尽可能避免这种情况,以简化事情。

例如使用这种方法:

import random

def doSomething() -> typing.List[dict]:
    # the old code we might choose not to change for some reason ...
    if random.random() <= 0.5:
        x = {'key': 'RIDE', '3': 27.3531}
    else:
        x = [{'key': 'GH', '3': 154.24}, {'key': 'RIDE', '3': 27.34}]

    # but we can compensate ...
    if isinstance(x, dict):
        x = [ x ]

    return x
#

现在我们使函数始终返回相同类型的数据。现在这对我们来说更方便:a) 它简化了调用者的处理,b) 首先简化了对返回数据的了解。

因此,将所有内容转换为仅返回单一类型的数据后,我们的主例程将简化为:

for item in x:
    print(item)

或者如果你想显示键和值:

for item in x:
    for k, v in item.items():
        print(k, "->", v)

或者您想对返回的数据进行何种类型的数据处理。

请记住,使用任何脚本或编程语言的经验法则:

始终以调用者易于使用且整个逻辑易于程序员理解的方式提供数据。使以良好的方式提供数据成为子例程的问题,而不是调用者的问题。尽可能简化来电者的生活。

(是的,你可以决定违反这个原则并且遵守它,但如果你这样做,那么你真的必须有一个很好的理由。那么你真的需要知道你在做什么,因为那时你有一个非常非常特殊的情况。让我根据我 25 年作为专业软件开发人员的经验告诉你:在 99.999% 的情况下,你没有如此特殊的情况。我觉得你的情况属于这种特殊情况的类别;-) )

相关问题