动态创建字典

时间:2014-12-02 17:48:52

标签: python string variables dynamic dictionary

我有几个变量命名如下:

self.box_1
self.box_2
self.box_3
self.square_1
self.square_2
self.square_3
self.triangle_1
self.triangle_2
self.triangle_3

我想创建一个包含所有“盒子”,“正方形”,“三角形”以及所有1,2和3的字典的字典。

类似的东西:

names = {'box':[self.box_1,self.box_2,self.box_3],
         'square':[self.square_1,self.square_2 ...}
numbers = {1:[self.box_1,self.square_1,self.triangle_1] 
           2:[self.box_2,self.square_2,... }

我设法创建一个小脚本来创建正确的字符串:

groups = ['box','square','triangle']

names = {}
for group in groups:
    g = []
    for n in xrange(1, 4):
        g.append('self.%s_%s' % (group, n))
    names[group] = g

numbers = {}
for n in xrange(1, 4):
    g = []
    for group in groups:
        g.append('self.%s_%s'%(group,n))
    numbers[n] = g

print "Names =",names
print "Number =",numbers

输出:

Names = {'box': ['self.box_1', 'self.box_2', 'self.box_3'], 'square': ['self.square_1', 'self.square_2', 'self.square_3'], 'triangle': ['self.triangle_1', 'self.triangle_2', 'self.triangle_3']}
Number = {1: ['self.box_1', 'self.square_1', 'self.triangle_1'], 2: ['self.box_2', 'self.square_2', 'self.triangle_2'], 3: ['self.box_3', 'self.square_3', 'self.triangle_3']}

正如您所看到的,它与所需的几乎相同,但变量的名称是字符串格式。 如何将字符串转换为变量名?

3 个答案:

答案 0 :(得分:2)

您需要使用getattr() function动态检索对象的属性:

names = {}
for group in groups:
    g = []
    for n in xrange(1, 4):
        g.append(getattr(self, '%s_%s' % (group, n))
    names[group] = g

但是,请考虑使用列表或词典代替属性;你总是可以索引到那些。 self.box[0]就像self.box_1一样简单,但现在您不必动态生成属性名称就可以访问所有框。

答案 1 :(得分:1)

最好避免这样做。

而不是:

self.box_1
self.box_2
self.box_3

你应该有一个可以像这样使用的列表:

self.box[0]
self.box[1]
self.box[2]

然后你就可以做到这一点:

names["box"] = self.box

for i in xrange(3):
    numbers[i] = []
    for thing in (self.box, self.square, self.triangle):
        numbers[i].append(thing[i])

答案 2 :(得分:0)

我认为这会非常接近你说你想要完成的事情。为简单起见,我将namesnumbers都设为defaultdict而不是dict

from __future__ import print_function
from collections import defaultdict
from pprint import pprint, pformat

# for testing purposes
class Box(object): pass
class Square(object): pass
class Triangle(object): pass

# global variables
shape_names = {'box', 'square', 'triangle'}
names = defaultdict(list)
numbers = defaultdict(list)

class MyClass(object):
    def __init__(self):
        self.box_1 = Box()
        self.box_2 = Box()
        self.box_3 = Box()
        self.square_1 = Square()
        self.square_2 = Square()
        self.square_3 = Square()
        self.triangle_1 = Triangle()
        self.triangle_2 = Triangle()
        self.triangle_3 = Triangle()

        # classify shape attributes created
        for name, value in self.__dict__.iteritems():
            prefix, suffix = name.split('_')
            if prefix in shape_names:
                names[prefix].append(value)
                numbers[int(suffix)].append(value)

obj = MyClass()
print('names:\n', pformat(dict(names)), sep='')
print()
print('numbers:\n', pformat(dict(numbers)), sep='')

输出:

names:                                                     
{'box': [<__main__.Box object at 0x02388BD0>,              
         <__main__.Box object at 0x02388BB0>,              
         <__main__.Box object at 0x02388B90>],             
 'square': [<__main__.Square object at 0x02388BF0>,        
            <__main__.Square object at 0x02388C10>,        
            <__main__.Square object at 0x02388C30>],       
 'triangle': [<__main__.Triangle object at 0x02388C90>,    
              <__main__.Triangle object at 0x02388C70>,    
              <__main__.Triangle object at 0x02388C50>]}   

numbers:                                                   
{1: [<__main__.Square object at 0x02388BF0>,               
     <__main__.Box object at 0x02388B90>,                  
     <__main__.Triangle object at 0x02388C50>],            
 2: [<__main__.Square object at 0x02388C10>,               
     <__main__.Box object at 0x02388BB0>,                  
     <__main__.Triangle object at 0x02388C70>],            
 3: [<__main__.Triangle object at 0x02388C90>,             
     <__main__.Square object at 0x02388C30>,               
     <__main__.Box object at 0x02388BD0>]}