具有相同键的(嵌套)词典的Pythonic替代方案?

具有相同键的(嵌套)词典的Pythonic替代方案?,python,class,dictionary,namedtuple,Python,Class,Dictionary,Namedtuple,我发现自己避免使用字典,因为它们的代码通常有近一半是重复的。我通常在嵌套字典中这样做,其中所有子字典都包含相同的键,但值不同 我手动创建了一个大型父字典,其中每个键都包含一个嵌套字典,用于外部模块。嵌套字典都使用相同的键来定义配置参数。这种用法是显式的,可以工作,但是为我手动创建的每个嵌套字典重新键入或复制/粘贴键感觉很愚蠢。我并不过分关注优化内存或性能,只是想知道我是否应该用另一种更具python风格的方式来实现这一点 作为一个常见的小例子和模式: people_dict = { "C

我发现自己避免使用字典,因为它们的代码通常有近一半是重复的。我通常在嵌套字典中这样做,其中所有子字典都包含相同的键,但值不同

我手动创建了一个大型父字典,其中每个键都包含一个嵌套字典,用于外部模块。嵌套字典都使用相同的键来定义配置参数。这种用法是显式的,可以工作,但是为我手动创建的每个嵌套字典重新键入或复制/粘贴键感觉很愚蠢。我并不过分关注优化内存或性能,只是想知道我是否应该用另一种更具python风格的方式来实现这一点

作为一个常见的小例子和模式:

people_dict = {
    "Charles Lindberg": {"address": "123 St.", 
                         "famous": True}, 
    "Me": {"address": "456 St.",
           "famous": False}
    }

>>>people_dict["Charles Lindberg"]["address"]
"123 St."
虽然字典支持显式代码,但定义具有重复键的嵌套字典既繁琐又容易出错。在本例中,一半嵌套字典是所有嵌套字典共有的代码重复代码。 我曾尝试使用元组消除重复的键,但发现这会导致脆弱的代码——任何位置的更改(而不是字典键)都会失败。这也会导致代码不明确且难以遵循

people_dict = {
        "Charles Lindberg": ("123 St.", True), 
        "Me": ("456 St.", False),
        }    

>>>people_dict["Charles Lindberg"][0]
"123 St."
相反,我编写了一个类来封装相同的信息:这个 成功减少重复代码

class Person(object):
    def __init__(self, address, famous=False):
        self.address = address
        self.famous = famous

people_dict = [
    "Charles Lindberg": Person("123 St.", famous=False), 
    "Me": Person("456 St."), 
    ]

>>>people_dict["Charles Lindberg"].address
"123 St." 
创建一个类似乎有点过分了。。。标准数据类型似乎太基本了

我想有更好的方法在Python中实现这一点,而不必编写自己的类?
在创建带有公共键的嵌套字典时,避免代码重复的最佳方法是什么?听起来好像您有一个数据矩阵,因为每个“行”都有相同的键(列),所以我要使用NumPy数组:

import numpy as np

dtype = [('name', object), ('address', object), ('famous', bool)]
people = np.array([
        ("Charles Lindberg", "123 St.", True),
        ("Me", "456 St.", False),
        ], dtype)

charlie = people[people['name'] == 'Charles Lindberg'][0]
print charlie['address']
或者使用更高级的熊猫:

import pandas as pd
people = pd.DataFrame(people_dict)
print people['Charles Lindberg']['address']

它可以很容易地将您的原始dict
people\u dict
直接加载到矩阵中,并提供类似的查找功能。

首先,您可以阅读上面的链接以获取有关名称元组的更多信息:

NamedTuples可以帮助您避免“重复代码”。您可以为地址创建一个namedtuple并使用它来定义。
我尤其喜欢宾语。面向对象有更好的解决方案。您可以创建一个将对象导出到dict的方法

对于函数范式,最好使用列表、数组和dict,因为有很多方法/函数可以帮助处理这个结构(map、reduce等)。如果你不想假装在你的应用程序中使用一些功能,请转到OO(面向对象)解决方案

问候
Andre

如果您想要一个dict,其中所有值都是具有相同或类似键的dict,您可以定义一个函数,该函数接受这些值并返回其中一个内部dict

def hash(address, famous): return {"address": address, "famous": famous}

people_dict = {
    "Charles Lindberg": hash("123 St.", true),
    "Me": hash("456 St.", false)
}

为什么要担心单独dict中的重复键呢?要扩展上述内容,您不需要担心嵌套dict中重复字符串键的(内存使用)问题。Python将该字符串存储在内存中一次,然后使用指向同一字符串的指针/引用。为了定义父词典,我最终复制并粘贴了一吨。这样做感觉是不对的,但我不知道有什么好的替代方案或最佳实践……如果您更多地从性能的角度来看,那么命名双工可能就是您想要的。如果你能更多地解释为什么你认为字典不是一个好的解决方案,它将帮助你找到更适合你的情况的解决方案。你想要的是一个命名的元组。它们就像你的小类一样,只是它们包含更多的功能,需要更少的代码来定义。尽管如此,我还是看不出人们是如何复制的?我认为您定义Person类是正确的,通过key access查找它是一种标准的、可接受的方法。Namedtuples比python对象更轻量级,但在设计方面不会真正为您节省太多精力。您还可以将用户输入一个行为类似于dic的类,具有更多自定义功能。@AdamHughes这是一个有用的细分-NamedTuple的轻量级特性与class对象之间肯定存在权衡。对于问题中定义的特定用法,我认为NamedTuple就足够了,而且它支持tuple方法。为什么您支持numpy方法而不是NamedTuple?我支持pandas,因为在我的应用程序中,我几乎总是需要在这样的框架上构建,最终我通常需要基本容器类型无法提供的功能。我想这取决于项目。另外,我真的是熊猫的拥护者,这是基于numpy的,但我不推荐一个纯粹的numpy方法,只是为了让OP清楚。只是为了清楚,从约翰指出的两种方法来看,我只会为熊猫方法而烦恼。实际上,很多numpy操作都可以在Pandas中完成,所以我避免直接使用numpy。