1

I have following function, which takes values from pandas dataframe columns and supplies arguments(s0_loc,s1_loc,.. upto ..,s12_loc if and only if their respective s0,s1,s2...,s12 is not-null) to another function. Also It will check whether s1 is null or not if and only if s0 is not null... Similarly it will check whether s2 is null or not iff s0,s1 is not null.. So on..

Based on above criteria I have written following function. But it's lengthy function... I want to reduce the piece of code in this function.

def compare_locality(p,p_loc,s0,s0_loc,s1,s1_loc,s2,s2_loc,s3,s3_loc,s4,s4_loc,s5,s5_loc,s6,s6_loc,s7,s7_loc,s8,s8_loc,s9,s9_loc,s10,s10_loc,s11,s11_loc,s12,s12_loc):
    loc = []
    if s0 != '' :
        loc.append(s0_loc)
        if s1 != '' :
            loc.append(s1_loc)
            if s2 != '' :
                loc.append(s2_loc)
                if s3 != '' :
                    loc.append(s3_loc)
                    if s4 != '' :
                        loc.append(s4_loc)
                        if s5 != '' :
                            loc.append(s5_loc)
                            if s6 != '' :
                                loc.append(s6_loc)
                                if s7 != '' :
                                    loc.append(s7_loc)
                                    if s8 != '' :
                                        loc.append(s8_loc)
                                        if s9 != '' :
                                            loc.append(s9_loc)
                                            if s10 != '' :
                                                loc.append(s10_loc)
                                                if s11 != '' :
                                                    loc.append(s11_loc)
                                                    if s12 != '' :
                                                        loc.append(s12_loc)
if len(loc) == 0:
    return ''
else:
    return compare(p_loc,*loc)

Can I get any suggestion on how to achieve this??

Avinash Clinton
  • 543
  • 1
  • 8
  • 19
  • 1
    we got that its a big if ladder. Can you show us some data and expected result. So we can recommend a different approach to the problem – Bharath M Shetty Jan 30 '18 at 15:59
  • Basically you're appending the `s*_loc` to `loc` if `s*` is not `''`. Why not create a boolean list and take all the `True`? Simply put why not do `['' == item for item in [s0,s1,s2 .... ]]` and then process all the values which are `False` – Sudheesh Singanamalla Jan 30 '18 at 15:59
  • Áou should be passing lists, not variables. That's what lists are for – whackamadoodle3000 Jan 30 '18 at 16:06
  • are you asking how to `zip` two lists? – C8H10N4O2 Jan 30 '18 at 17:13
  • I will be comparing p_loc value with s0_loc,s1_loc... in another function, if they exists... if s0 is present i'm appending s0_loc, if s1 is present i'm passing s1_loc... so on... – Avinash Clinton Jan 31 '18 at 13:16

3 Answers3

6

To go with Sandeep's answer, you can build the two lists locally from the giant list of arguments:

def compare_locality(p,p_loc,s0,s0_loc,s1,s1_loc,s2,s2_loc,s3,s3_loc,s4,s4_loc,s5,s5_loc,s6,s6_loc,s7,s7_loc,s8,s8_loc,s9,s9_loc,s10,s10_loc,s11,s11_loc,s12,s12_loc):
    locs = []
    ss = [s0, s1, s2, ..., s12]
    s_locs = [s0_loc, ..., s12_loc]
    for s, s_loc in zip(ss, s_locs):
        if s == '':
            break
        locs.append(s_loc)

if len(locs) == 0:
    return ''
else:
    return compare(p_loc,*locs)
chepner
  • 497,756
  • 71
  • 530
  • 681
  • You should probably test `if s == '': break` explicitly. For example, `s` could be another falsy such as zero or None that the OP wants to capture. – Alexander Jan 30 '18 at 16:09
  • @Alexander That would be very bad design. – chepner Jan 30 '18 at 16:11
  • Perhaps, but it matches the OPs current usage pattern and without knowing what the underlying data represents one never knows... – Alexander Jan 30 '18 at 16:13
2

Why don't you take in two arrays, one for s and the other for s_loc? You can validate the lengths and do your array building with a for loop? Since subsequent additions to the array are dependent on previous additions, you might want to take a look at the break statement if you are unaware of it.

2

Iterate over the list. I failed to get it to work without the intermediate grouped list. See also iterating over two values of a list at a time in python.

Tested (3.5):

>>> li = ['a', 'ax', 'b', 'bx', '', 'cx', 'd', 'dx']
>>> it = iter(li)
>>> grouped = [(x,next(it)) for x in it]
>>> grouped
[('a', 'ax'), ('b', 'bx'), ('', 'cx'), ('d', 'dx')]
>>> loc = [y for x,y in grouped if x]
>>> loc
['ax', 'bx', 'dx']

Of course, if you have two lists in the first place, you can just skip on merging and separating them again.

Risadinha
  • 16,058
  • 2
  • 88
  • 91