2

我里面有一个dict包含另一个dict

d1 = {'a':{'p':1, 'q':2, 'r':'abc'}, 
      'b':{'p':5, 'q':6, 'r':["google", "pypi.org"]}
     }
url1 = "https://google.com"
url2 = "https://abc.com"

现在我想做的是检查r两者的值,dict values但我不想要任何代码冗余。这怎么可能?

我现在正在做的是:-

for k, v in d1.iteritems():
    if isinstance(v['r'], list):
        for l in v['r']:
            if url1.find(l):
                ..Do something..
            else:
                continue
    else:
        if url1.find(v['r'):
                ..Do Something same as above..
            else:
                continue

现在问题出现了相同的Do something 重复 2 次,有没有办法通过理解或任何其他方法来解决冗余,除了函数制作和调用

编辑——代码已经在一个大型函数定义中,所以除了创建另一个函数并调用它之外,请提供其他解决方案。

4

3 回答 3

2

如果您对 python 代码的性能非常认真,并且愿意接受某些风格上的妥协,那么假设您使用pypy ,以下表单的运行速度将与手动内联代码一样快:

def inner():
    pass

for k, v in d1.items():
    if isinstance(v['r'], list):
        for l in v['r']:
            if url1.find(l):
                inner()
            else:
                continue
    else:
        if url1.find(v['r']):
            inner()
        else:
            continue

有关包含非空内部代码和一些计时代码的更实际的示例,请参阅此链接。

请注意,正如您所写,此版本比 CPython 下的内联版本慢得多,后者当然没有 JIT 内联。

于 2014-05-29T11:08:15.213 回答
2

您可以转换非列表项,即。在这种情况下将字符串添加到列表中,然后简单地遍历该列表。你不需要那else: continue部分:

for k, v in d1.iteritems():
    value = v['r'] if isinstance(v['r'], list) else [v['r']]
    for l in value:
        if url1.find(l):
           #Do something..
于 2014-05-29T09:52:02.110 回答
1

异想天开是对的。使用函数将是这里的最佳解决方案。使用函数调用的开销可以忽略不计,并且可能比创建新列表和循环长度为 1 的列表要少。

但是,如果您确实想不惜一切代价避免代码重复并避免多次函数调用,您可能需要考虑将代码重写为生成器函数。这将产生您想要一次处理的项目。

def loop(d1):
    for k, v in d1.iteritems():
        if isinstance(v['r'], list):
            for l in v['r']:
                if url1.find(l):
                    yield l
                else:
                    continue
        else:
            if url1.find(v['r']):
                yield v['r']
            else:
                continue

for item in loop(d1):
    print "do something"
于 2014-05-29T09:53:42.490 回答