2015-11-06 65 views
2

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

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

如果你想让你的代码更快,我相信使用'filter'函数比列表comp更快。当我打字的时候,@MadPhysicist发布了我要说的话:你可以分配'v'然后检查'len(v)',这样list comp只运行一次 –

+0

我会研究'filter'函数。谢谢。 – ketar

回答

2

它会让你的代码稍微快一点,更重要的是,可读性更强,更不容易出错。无论您创建的列表是否通过测试len(...) == 1,它都会被计算。那么为什么不计算一次呢?当然,你将不得不与else-if更换elif

# 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是发电机,这是懒洋洋地evalutated iterables对象。他们实际上并没有计算清单。你可以通过每一个,并找到匹配时找到,忽略其他人。直到陈述l = list(gen)才会计算列表。我认为第二种方法更多是Pythonic,因为无论您拥有多少条件,它都使用一个for循环,而不是从页面前进的一系列else语句。

+0

我有5个其他elif,检查700,000行的不同条件。在这种情况下,我必须在if和elifs之外定义“v”。 (这些变量从这个v测试不同的条件)。如果这些代码是针对每一行计算的,那真的会减慢代码的速度,但是我希望这些v变量只能在第一个if和before之前的elifs失败时计算,以便它们不会每次都创建。 – ketar

+0

你应该认识到,如果len([项目在propadd中item [0] == row1 [8]和harversine(custx,custy,item [2],item [3])<1500])== 1 '计算'v'的值并将其传递给'len()'?我所做的只是将一个指向列表的指针赋给一个临时变量。 –

+0

此外,不要试图优化你的代码,直到你运行它,并知道有问题。可读性比优化更重要。 –