我为糟糕的头衔道歉。不确定如何说出我的问题。
我下面的代码使用名为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]
答案 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
在这种情况下,表达式v
,k
,m
是生成器,它们是延迟评估的迭代对象。他们实际上并没有计算清单。您可以浏览每一个并分配匹配时找到的那个,忽略其他的。在语句l = list(gen)
之前不会计算列表。我认为第二种方法更像是Pythonic,因为它使用单个for
循环,无论你有多少条件,而不是一系列else
语句从页面进行游戏。