简体   繁体   中英

Assign variable name to list in if statement python

I apologize for the poor title. Wasn't sure exactly how to word my question. I have code below which uses a list of tuples called propadd . The if statement tests the tuples for matching conditions. If the match matches to only 1 tuple from the list of tuples, it executes the exact same code as that in the if statement so as to assign this matching tuple to variable v in order to update the cursor rows with values from this matching tuple. I would like to know if there's a way to get rid of the assignment of the exact same code to v after the if statement. Is it possible to assign the list to v in the if statement while checking for the length of the matches? This is part of a larger amount of code that follows this methodology. I believe that doing this will make my code faster.

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]

It will make your code slightly faster, and what is much more important, more readable and less error prone. Whether the list you create passes the test len(...) == 1 or not, it is computed. So why not just compute it once? Of course you will have to replace elif with 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]

Coming from C, this is much more cumbersome than if(v = (....)) { } else ... . However, there is another way to do this. You can use the fact that each expression in the list comprehensions is a generator:

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

In this case, the expressions v , k , m are generators, which are objects that are lazily evalutated iterables. They are not actually computing the list. You can go through each one and assign the one that matches when it is found, ignoring the others. The list is not computed until the statement l = list(gen) . I think the second approach is much more Pythonic because it uses a single for loop no matter how many conditions you have, instead of a sequence of else statements marching off the page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM