【问题标题】:Get name of dictionary获取字典名称
【发布时间】:2014-08-05 18:58:54
【问题描述】:

我发现自己需要遍历一个由字典组成的列表,并且对于每次迭代,我都需要我正在迭代的字典的名称。

这是一个 MRE(最小可重现示例)。
dicts 的内容无关紧要:

dict1 = {...}
dicta = {...}
dict666 = {...}

dict_list = [dict1, dicta, dict666]

for dc in dict_list:
    # Insert command that should replace ???
    print 'The name of the dictionary is: ', ???

如果我只使用??? 所在的dc,它将打印字典的全部内容。如何获取正在使用的字典的名称?

【问题讨论】:

  • 字典本身没有名称。作为一般规则,变量本身没有名称。如果您试图获取分配给它的变量的名称,我认为这是不可能的,因为您可能有多个变量指向同一个字典。

标签: python dictionary


【解决方案1】:

不要使用dict_list,如果您需要他们的名字,请使用dict_dict。但实际上,您真的不应该这样做。不要在变量名中嵌入有意义的信息。很难得到。

dict_dict = {'dict1':dict1, 'dicta':dicta, 'dict666':dict666}

for name,dict_ in dict_dict.items():
    print 'the name of the dictionary is ', name
    print 'the dictionary looks like ', dict_

或者创建一个dict_set 并迭代locals(),但这比罪恶更难看。

dict_set = {dict1,dicta,dict666}

for name,value in locals().items():
    if value in dict_set:
        print 'the name of the dictionary is ', name
        print 'the dictionary looks like ', value

再说一遍:比罪恶更丑陋,但它确实有效。

【讨论】:

  • @Gabriel 如果名称有意义,它应该在您可以访问的字典中。否则将其视为比内存位置更容易记住的一次性东西(它实际上只是指向0xFAC4928FD9 的指针)
  • @Gabriel 对你的程序真正有意义的任何信息都应该存储在变量数据中,而不是变量名中。
  • 一个更好的表述方式是“不要将对程序有意义的信息嵌入到变量名中”,因为它很难检索并且很容易被代码更改。
  • @Gabriel:另请参阅Keep data out of your variable names,了解一些不这样做的充分理由。
  • @Gabriel 不要觉得太受训诫。每个人都在某个时候这样做,这就是为什么现在强烈建议不要这样做。大约一年前,我自己编写了一个脚本,该脚本必须从大约 100 台机器上收集大约 12 个文件的文件大小信息,以找出哪些机器没有清除它们的历史文件。我为每个文件设计了FILENAME = [('machine_name', size), ...],这是我写过的最大的废话脚本。我什至不能再使用它了,因为我不知道如何维护它了——不得不在一个月前从头开始重写。
【解决方案2】:

您还应该考虑为每个字典添加一个“名称”键。

名字是:

for dc in dict_list:
    # Insert command that should replace ???
    print 'The name of the dictionary is: ', dc['name']

【讨论】:

    【解决方案3】:

    对象在 Python 中没有名称,名称是一个标识符,可以将其分配给 一个对象,并且可以将多个名称分配给同一个对象。

    然而,一种面向对象的方式来做你想做的事情是继承内置的 dict 字典类并向它添加一个 name 属性。它的实例的行为与普通字典完全一样,并且几乎可以在任何普通字典可以使用的地方使用。

    class NamedDict(dict):
        def __init__(self, *args, **kwargs):
            try:
                self._name = kwargs.pop('name')
            except KeyError:
                raise KeyError('a "name" keyword argument must be supplied')
            super(NamedDict, self).__init__(*args, **kwargs)
    
        @classmethod
        def fromkeys(cls, name, seq, value=None):
            return cls(dict.fromkeys(seq, value), name=name)
    
        @property
        def name(self):
            return self._name
    
    dict_list = [NamedDict.fromkeys('dict1', range(1,4)),
                 NamedDict.fromkeys('dicta', range(1,4), 'a'),
                 NamedDict.fromkeys('dict666', range(1,4), 666)]
    
    for dc in dict_list:
        print 'the name of the dictionary is ', dc.name
        print 'the dictionary looks like ', dc
    

    输出:

    the name of the dictionary is  dict1
    the dictionary looks like  {1: None, 2: None, 3: None}
    the name of the dictionary is  dicta
    the dictionary looks like  {1: 'a', 2: 'a', 3: 'a'}
    the name of the dictionary is  dict666
    the dictionary looks like  {1: 666, 2: 666, 3: 666}
    

    【讨论】:

    • 受到启发!我喜欢它:D
    【解决方案4】:

    如果您想读取名称和值

    dictionary={"name1":"value1","name2":"value2","name3":"value3","name4":"value4"}
    for name,value in dictionary.items():
        print(name)
        print(value)
    

    如果您只想读取名称

    dictionary={"name1":"value1","name2":"value2","name3":"value3","name4":"value4"}
    for name in dictionary:
        print(name)
    

    如果您只想读取值

    dictionary={"name1":"value1","name2":"value2","name3":"value3","name4":"value4"}
    for values in dictionary.values():
        print(values)
    

    这是你的答案

    dic1 = {"dic":1}
    dic2 = {"dic":2}
    dic3 = {"dic":3}
    dictionaries = [dic1,dic2,dic3]
    for i in range(len(dictionaries)):
      my_var_name = [ k for k,v in locals().items() if v == dictionaries[i]][0]
      print(my_var_name)
    

    【讨论】:

    • 你误解了 Habibur 的问题。我的意思是字典本身的名称,而不是里面的键和参数。
    • Gabriel 我已经更新了我的答案,请检查。谢谢
    【解决方案5】:

    以下内容不适用于标准字典,但适用于集合字典和计数器:

    from collections import Counter
    
    # instantiate Counter ditionary
    test= Counter()
    
    # create an empty name attribute field
    test.name = lambda: None
    
    # set the "name" attribute field to "name" = "test"
    setattr(test.name, 'name', 'test')
    
    # access the nested name field
    print(test.name.name)
    

    这不是最漂亮的解决方案,但它很容易实现和访问。

    【讨论】:

      【解决方案6】:

      这是我对描述性错误消息的解决方案。

      def dict_key_needed(dictionary,key,msg='dictionary'):
          try:
              value = dictionary[key]
              return value
          except KeyError:
               raise KeyError(f"{msg} is missing key '{key}'")
      

      【讨论】:

        猜你喜欢
        • 2021-08-02
        • 2020-02-06
        • 1970-01-01
        • 2013-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-24
        • 1970-01-01
        相关资源
        最近更新 更多