将变量名称分配给 if 语句中的列表 python

Assign variable name to list in if statement python

我为糟糕的标题道歉。不确定如何表达我的问题。 我有下面的代码,它使用一个名为 propadd 的元组列表。 if statement 测试元组的匹配条件。如果匹配仅匹配元组列表中的 1 个元组,它会执行与 if 语句中完全相同的代码,以便将此匹配元组分配给变量 v,以便使用来自此匹配元组的值更新游标行。我想知道是否有办法摆脱在 if 语句之后将完全相同的代码分配给 v 的情况。是否可以在检查匹配长度的同时将列表分配给 if 语句中的 v?这是遵循此方法的大量代码的一部分。我相信这样做会使我的代码更快。

if len([item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500]) == 1:
        v=[item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500]
        row1[1]=v[0][1]
        row1[2]=v[0][2]
elif len([item for item in custadd if item[0]==row1[4]]) == 1:
        k=[item for item in custadd if item[0]==row1[4]]
        row1[1]=k[0][1]
        row1[2]=k[0][2]
elif len([item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()]) == 1
        m=[item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()]
        row1[1]=m[0][1]
        row1[2]=m[0][2]

它会让你的代码稍微快一些,更重要的是,它更易读,更不容易出错。无论您创建的列表是否通过 len(...) == 1 测试,都会对其进行计算。那么为什么不只计算一次呢?当然,您必须将 elif 替换为 else-if:

# Compute v
v = [item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500]
if len(v) == 1:
    row1[1]=v[0][1]
    row1[2]=v[0][2]
else:
    # If v fails, compute k
    k = [item for item in custadd if item[0]==row1[4]]
    if len(k) == 1:
        row1[1]=k[0][1]
        row1[2]=k[0][2]
    else:
        # If k fails, compute m
        m = [item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()]
        if len(m) == 1:
            row1[1]=m[0][1]
            row1[2]=m[0][2]

来自C,这比if(v = (....)) { } else ...麻烦多了。但是,还有另一种方法可以做到这一点。您可以使用列表理解中的每个表达式都是生成器这一事实:

v = (item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500)
k = (item for item in custadd if item[0]==row1[4])
m = (item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group())
for gen in (v, k, m):
    l = list(gen)
    if len(l) == 1:
        row1[1] = l[0][1]
        row1[2] = l[0][2]
        break

在这种情况下,表达式 vkm 是生成器,它们是延迟计算的可迭代对象。他们实际上并没有计算列表。您可以遍历每一个并分配找到匹配的那个,忽略其他的。直到语句 l = list(gen) 才计算列表。我认为第二种方法更像 Pythonic,因为无论您有多少条件,它都使用单个 for 循环,而不是一系列 else 语句离开页面。