嵌套for循环以列出具有不同“ if”条件的理解

时间:2019-01-07 14:57:19

标签: python python-3.x list-comprehension nested-loops

我正在尝试将此嵌套循环转换为列表理解,但我不确定是否可能,因为“ tmp”列表中的项目可能具有不同的值。这是最好的方法吗?谢谢!

LAG

3 个答案:

答案 0 :(得分:3)

嵌套的理解不是很容易阅读

一个简单的

[something for something in container if something > 9]

很棒,但是嵌套的嵌套经常令人困惑

您可以简单地将循环移至生成器函数中-仍然可以读取并允许延迟迭代

def no_idea_what_this_represents():
    for a in range(-13, 1):
        for b in range(0,4):
            for c in range(6, 49):
                for d in range(48, 94):
                    tmp = [0 for i in range(100)]
                    for i in range(100):
                        if raw_x[i] >= b and raw_y[i] >= d:
                            tmp [i] = -1
                        if raw_x[i] <= a and raw_y[i] <= c:
                            tmp [i] = 1
                    yield tmp

final = [signs for signs in no_idea_what_this_represents()]

编辑:只是一个有目的的附录-这样,可以为复杂的嵌套循环命名(出于明显的原因,我将其命名为no_idea_what_this_represents),但是当程序员看到时

possible_views = [matrix for matrix in camera_matrices()]

他立刻知道那是什么意思

possible_views = [device.matrix 
                  for devices in itertools.chain(connected_devices(), buffered_devices()
                  for device in devices
                  if device.type=='camera']

使程序员读了很多行,并且不清楚发生了什么

答案 1 :(得分:2)

您的算法具有较大的时间复杂度。首先查看这是否真的是您所需要的。一旦确定需要一个具有4个嵌套级别的嵌套for循环,就可以定义一个函数以在列表理解中使用 in

在这种情况下,请注意内置的map可以接受多个可迭代的参数。 functools.partial允许您使用预设参数定义函数。

from functools import partial

def get_val(x, y, a, b, c, d):
    if x <= a and y <= c:
        return 1
    if x >= b and y >= d:
        return -1
    return 0

final = [list(map(partial(get_val, a=a, b=b, c=c, d=d), raw_x, raw_y)) \
         for a in range(-13, 1) \
         for b in range(0, 4) \
         for c in range(6, 49) \
         for d in range(48, 94)]

答案 2 :(得分:2)

这可以用一个表达式完成,尽管我不确定可读性是否得到改善:

final = [
    [
        +1 if x <= a and y <= c
        else -1 if x >= b and y >= d
        else 0
        for x, y in zip( raw_x, raw_y )
    ]
    for a in range(-13, 1)
    for b in range(0, 4)
    for c in range(6, 49)
    for d in range(48, 94)
]

请注意,我假设您要遍历raw_xraw_y整个,而不是每次都精确地使用100个元素:这个问题意味着每100个-时间,但是如果意图确实是要经历整个序列,那么最好不要在其中硬编码100。如果我对意图有误,可以将内在理解for循环更改为for i in range(100),并在条件表达式中使用raw_x[i]raw_y[i]而不是{{1 }}和x