如何在不损失效率的情况下将此代码转换为1线性代码?

时间:2019-04-18 13:32:44

标签: python optimization

为了提高可读性,我想将此代码转换为1-liner。 变量tup_ranges是2个值的元组,例如(20, 40)。如果elt的值包括在此范围内,则检索与此值n对应的密钥。

identification = dict()
for elt in combination:
    for n, tup_range in ranges.items():
        if tup_range[0] <= elt and elt <= tup_range[1]:
            identification[elt] = n

不知何故,我想不出这段代码的好文字...

identification = {elt: [n for n, tup_range in ranges.items() if tup_range[0] <= elt and 
                        elt <= tup_range[1]][0] for elt in combination}

有效,但是由于中间创建了列表,所以速度较慢...反正要摆脱这个仅包含一个元素的列表?

要尝试:

ranges = {25: (20, 32), 35: (33, 45)}
combination = (30, 30, 40)
# Output:
{30: 25, 40: 35}

P.S:确实,这个问题会在代码审查中占有一席之地,但是我觉得这主要是对字典理解的错误设计。

1 个答案:

答案 0 :(得分:3)

单线版可能更具可读性

identification = {elt: n for n, tup_range in ranges.items() for elt in combination if tup_range[0] <= elt <= tup_range[1] }
#{30: 25, 40: 35}

identification = {elt: n for n in ranges for elt in combination if ranges[n][0] <= elt <= ranges[n][1] }

只是尝试定时两种方法

ranges = {25: (20, 32), 35: (33, 45)}
combination = (30, 30, 40)
identification = {}
import time
start = time.time()
for elt in combination:
    for n, tup_range in ranges.items():
        if tup_range[0] <= elt and elt <= tup_range[1]:
            identification[elt] = n
end = time.time()
print(end-start)
#1.2159347534179688e-05
ranges = {25: (20, 32), 35: (33, 45)}
combination = (30, 30, 40)
identification = {}
import time
start = time.time()
identification = {elt: n for n in ranges for elt in combination if ranges[n][0] <= elt <= ranges[n][1] }
end = time.time()
print(end-start)
#5.0067901611328125e-06

dict理解速度提高了10倍