Function to combine list elements I was working on a little project that at the end of the script would write to a CSV file. I had to create a function that would combine multiple list elements of the same size into a single one. I would like to see if there is a more efficient way of doing this since I feel the way I did might not be the most efficient one. I created the function due to the need of capturing different number instances from a large CSV file. The reason on hwy I'm using "-" is because it was easier for me to count list elements.      

def clean(li):
    tl = len(li)#2
    amount = len(li[0].split(","))
    if tl == 1:
        return ",".join(li)
    else:     
        hold = "-," * amount
        hold = hold[:-1]
        d = hold.split(",")   
        for i in li:
            con = i.split(",")
            for z, x in enumerate(d):  
                if d[z] == con[z]:
                    pass
                elif d[z] &gt; con[z]:                
                    d[z] = d[z]
                else:
                    d[z] = con[z]
        return ",".join(d)

a = ['-,-,17,-,-,-,', '-,-,-,17,-,17,']
b = ['-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,5,-,-,-,-,-,-,-,-']   
c = ['19,-,-,-,-,-,','-,-,19,-,-,19,','-,-,-,-,19,-,']
ss = clean(a)
se = clean(b)
sq = clean(c)


Output:

-,-,17,17,-,17,-
-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,5,-,-,-,-,-,-,-,-
19,-,19,-,19,19,-
It is quite hard to understand what your code is supposed to do. Let's try to progress little by little.

I've based my analysis on the test cases you have provided.

if tl == 1:

A list with a single element seems to be handled in a special way. If we replace the check with if tl == 1 and False:, we can see that the result is the same if we don't handle this case in a particular way.

I've removed the corresponding check.

hold

You are performing some super tricky logic involving string manipulation, list slicing and split. I realised that the whole thing does the same thing as d = ['-'] * amount.

Comparison of d[z] and con[z]

You are handling the three different cases here. Funny thing is that you have a case where you do nothing (pass) and one where you do something which looks like nothing to me (d[z] = d[z]). At the end of the day, I have the feeling that this could be written : d[z] = max(x, con[z]).

Hard coded strings

You have ',' in multiple places. If you ever want to change this, this will be pretty akward. You could store this in a variable on its own. Even better, you could make this a parameter with a default value. You have the benefit of making things easier for you as a developer of the function but also as a user of the function because it is easier to change its behavior if needed.

At this point, the code looks like:

def clean(li, sep=','):
    amount = len(li[0].split(sep))
    d = ['-'] *  amount
    for i in li:
        con = i.split(sep)
        for z, x in enumerate(d):
            d[z] = max(x, con[z])
    return sep.join(d)


Splitting string once

As you only care about the splitted version of the string, it would probably be interesting to split them at the very beginning so that you don't have to worry about this later on in the function.

splitted = [i.split(sep) for i in li]


Input handling

A few special cases could lead to troubles :


if len(li) == 0, your code will crash.
if the elements of splitted (which are lists of strings) have different lengths, your code will either crash (if a list is smaller that the first one) or ignore additional elements (if a list is bigger than the first one).


You might want to handle this properly.

Now, the code looks like :

def clean(li, sep=','):
    splitted = [i.split(sep) for i in li]
    if not splitted:
        return "invalid input" # or anything you like
    amount = len(splitted[0])
    if any(len(s) != amount for s in splitted):
        return "invalid input 2" # or anything you like
    d = ['-'] *  amount
    for s in splitted:
        for z, (dz, sz) in enumerate(zip(d, s)):
            d[z] = max(dz, sz)
    return sep.join(d)