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

时间:2015-11-06 18:57:38

标签: python list tuples arcpy

我为糟糕的头衔道歉。不确定如何说出我的问题。 我下面的代码使用名为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]

1 个答案:

答案 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语句从页面进行游戏。