0

我正在以pythonic的方式寻求帮助。

到目前为止我的代码。
我创建了一个生成器来创建一个字典,其中包含一个元组作为链接到我想稍后在我的项目中使用的对象的键。
我确信有更好的方法来做到这一点。我作为字典和列表理解的尝试没有成功。

app = models.get_app('djangoapp')
appmodels = models.get_models(app)

gen = mapEntGen(appmodels)  
d = {}  
for x in gen:  
    d.update(x)   

为了更清楚我的对象是什么样的。

for x in gen:
    print(x)

{('in', 1): <class 'djangoapp.models.entrance01IN'>}
{('out', 1): <class 'djangoapp.models.entrance01OUT'>}
{('in', 2): <class 'djangoapp.models.entrance02IN'>}
{('out', 2): <class 'djangoapp.models.entrance02OUT'>}
...

这些是我失败的理解尝试

{d: aDict for aDict in mapEntGen(appmodels)}  
d = {key: value for (key, value) in gen}  
d = {key: value for (key, value) in mapEntGen(appmodels[1:])}  

我认为问题很可能是它已经是一本字典,而不是其他两种类型。这可以用作键值对。

----> 1 for k, v in gen:
      2     d[k] = v
      3 

ValueError: need more than 1 value to unpack

这是我用于生成器的其他代码,用于构建对象映射和查找对象的键。

def mapEntGen(EntranceObj = []):    
    for x in EntranceObj:
        thisEnt = (x._meta.verbose_name[10:],
                   int(x._meta.verbose_name[8:10]))
        aDict = {thisEnt : x}
        yield aDict

它可能看起来像重复,但我尝试过的所有示例都没有按照我迄今为止尝试过的所有示例工作。

4

2 回答 2

1

回答这里显示的问题的最简单方法是丢弃 mapEntGen,并执行以下操作:

d = {((x._meta.verbose_name[10:],
       int(x._meta.verbose_name[8:10])):x 
           for x in EntranceObj}

无需创建不同的字典然后将它们组合起来。


如果您热衷于使用生成器 - 为什么要返回字典,而字典只有一个键和值?让它返回一个元组:

def mapEntGen(EntranceObj = []):    
    for x in EntranceObj:
        thisEnt = (x._meta.verbose_name[10:],
                   int(x._meta.verbose_name[8:10]))
        yield (thisEnt, x)

然后得到d很容易:

d = dict(mapEntGen(appmodels))

如果你想使用你的生成器:

mapEntGen(appmodels)生成字典 - 像这样对待它们。当你想要迭代他们的项目时,你必须调用 iteritems,然后迭代它们。这应该有效:

d = {key:value for subdct in gen for key, value in subdct.iteritems()}  

只是为了确保您理解理解,这相当于执行以下操作:

d = {}
for subdct in gen:
    for key, value in subdct.iteritems():
        d[key] = value

(当然gen可以换成mapEntGen(appmodels)

于 2014-08-26T20:18:30.490 回答
1

只是为了给你的代码一个完全不同的方向,这可能更具可读性和可用性,这取决于你的代码的其余部分:

代替 mapGenEnt,让我们从 appModels 创建两个单独的生成器(不管是什么):

  1. 代码列表(稍后用作键,例如('out', 1).
  2. 实际对象/模型的列表(您稍后将其用作值,例如<class 'djangoapp.models.entrance01IN'>.

所以,假设你有这两个生成器:

def code_names(EntranceObj):
   return ((entrance._meta.verbose_name[10:], int(entrance._meta.verbose_name[8:10]) for entrance in EntranceObj)

def entries(EntranceObj):
   return EntranceObj    # Shorter than: (entrance for entrance in EntranceObj)

现在我们有两个功能明确地做自己的事情,我们必须创建d. 简单,使用zipor itertools.izip

d = dict(zip(code_names(appmodels), entries(appmodels)))

为了进一步提高可读性,我个人会给这个函数起一个名字,比如generate_model_entries(appmodels)

def generate_model_entries(models):
    return dict(zip(code_names(models), entries(models)))

d = generate_model_entries(appmodels)

PS:如果您有一个比x循环变量更准确的名称,请;用它。

于 2014-08-26T21:15:21.540 回答