使用多个for和ifs / elifs缩短循环以列出理解

时间:2016-11-06 13:32:19

标签: python list dictionary

我有这段代码,其中字典键是函数,值是包含关键字的列表。它搜索列出的t,并查看它是否在字典值的列表中。如果是,则运行该值的函数[key]。如果没有,它将运行NowThis功能。 count变量就是t'hello hi'的情况。

dct = {doThis:['hi','hello'],
       doThat:['bye','goodbye']}

t = 'hi there' # or 'test'|'goodbye'|'hello hi'
count=0
for listValue in t.split():
    if count > 1 or count < 0:
        break
    elif listValue in [n for v in dct.values() for n in v]:
        for key,vl in dct.iteritems():
            if listValue in vl:
                key()
                count+=1
    elif count==0:
        nowThis()
        count -=1

我确实有这个代码的先前版本,它只适用于if,而且我很容易将其转换为列表理解:

[key() for listValue in t.split() if listValue in [n for v in dct.values() for n in v] for key,vl in dct.iteritems() if listValue in vl]

但是,我无法将当前代码转换为类似列表的理解。

1 个答案:

答案 0 :(得分:2)

正如评论中所解释的,这里使用列表理解没有任何好处。它实际上会更慢,因为你要创建一个你并不想要的列表。此外,将list comp纯粹用于其副作用被认为是糟糕的设计。

正如我在评论中提到的那样,你的字典设计是错误的,所以你没有获得使用字典的好处,即,dict可以快速测试是否存在密钥,并且它可以快速检索与键相关联的值。

假设您当前的代码符合您的要求,这是一种更好的编写方式。

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
]

<强>输出

def do_this():
    print 'Do This!\n'

def do_that():
    print 'Do That!\n'

def now_this():
    print 'Now This!\n'

dct = {
    'hi': do_this,
    'hello':  do_this,
    'bye': do_that,
    'goodbye': do_that,
}

data = ('hi there', 'python', 'goodbye hello', '')
for t in data:
    v = t.split(None, 1)[0] if t else ''
    print [t, v]
    dct.get(v, now_this)()

以下是没有['hi there', 'hi'] Do This! ['python', 'python'] Now This! ['goodbye hello', 'goodbye'] Do That! ['', ''] Now This! 语句的for循环的更紧凑版本:

print

我们使用条件表达式(for t in data: dct.get(t.split(None, 1)[0] if t else '', now_this)() ),因此我们可以处理t.split(None, 1)[0] if t else ''为空字符串的时间。这是一个不太可读的替代版本。 :)

t

如果保证 for t in data: dct.get((t.split(None, 1) or [''])[0], now_this)() 永远不会是空字符串,那么您可以使用简单版本:

t