Skip to content Skip to sidebar Skip to footer

Combine Elements Of Lists If Some Condition

How do I combine the elements of a list if some condition is met. I've seen posts about combining elements of a list, but not with some condition. Say I have a list containing lis

Solution 1:

Use itertools.groupby:

>>> from itertools import groupby
>>> out = []
>>> for lst in words:
    d = []
    for k, g in groupby(lst, lambda x: '!'in x):
        if k:
            d.append(', '.join(g))
        else:
            d.extend(g)
    out.append(d)
... >>> out
[['this', 'that!', 'riff', 'raff'],
 ['hip', 'hop!, flip!', 'flop'],
 ['humpty', 'dumpty!, professor!, grumpy!']]

Solution 2:

Here's my solution:

words = [
    ['this','that!','riff','raff'],
    ['hip','hop!','flip!','flop'],
    ['humpty','dumpty!','professor!','grumpy!']
]

output = []
for wl in words:
    out_wl = []
    bang_wl = []
    for w in wl:
        if'!' in w:
            bang_wl.append(w)
        else:
            if bang_wl:
                out_wl.append(','.join(bang_wl))
                bang_wl = []
            out_wl.append(w)
    if bang_wl:
        out_wl.append(','.join(bang_wl))
    output.append(out_wl)

print output

Output:

[['this', 'that!', 'riff', 'raff'], ['hip', 'hop!,flip!', 'flop'], ['humpty', 'dumpty!,professor!,grumpy!']]

bang_wl accumulates words with ! until it hits a word that doesn't contain a !. At this point, it joins the words in bang_wl and appends to the output_wl list.

Solution 3:

result = []

for sub_lst in words:
    result.append([])
    temp = ""for ele in sub_lst:
        if not temp and not "!" in ele:
            result[-1].append(ele)
        elif temp and not "!" in ele:
            result[-1].append(temp)
            result[-1].append(ele)
            temp = ""else:
            temp += "," + ele if temp else ele
    if temp:
        result[-1].append(temp)
 [['this', 'that!', 'riff', 'raff'], ['humpty', 'dumpty!,professor!,grumpy!'], ['hip', 'hop!,flip!', 'flop']]

If you want all words with a ! to be joined including words separated by words that don't contain a ! i.e ['humpty', 'dumpty!', 'professor!', 'grumpy!',"foo","bar!"] would become ['humpty', 'foo', 'dumpty!,professor!,grumpy!,bar!']:

result = []
for sub_l in words:
    result.append([])
    temp = ""for word in sub_l:
        if"!" in word:
            temp += "," + word if temp else word
        else:
            result[-1].append(word)
    result[-1].append(temp)

Some timings show @vikramls is the most efficient and the itertools solution is the least efficient.:

In [31]: %%timeit
   ....: result = []
   ....: for sub_lst in words:
   ....:     result.append([])
   ....:     temp = ""
   ....:     for ele in sub_lst:
   ....:         if not temp and not "!" in ele:
   ....:             result[-1].append(ele)
   ....:         elif temp and not "!" in ele:
   ....:             result[-1].append(temp)
   ....:             result[-1].append(ele)
   ....:             temp = ""
   ....:         else:
   ....:             temp += "," + ele if temp else ele
   ....:     if temp:
   ....:         result[-1].append(temp)
   ....: 
100000 loops, best of 3: 16 µs per loop

In [32]: %%timeit
output = []
for wl in words:
    out_wl = []
    bang_wl = []
    for w in wl:
        if '!' in w:                   
            bang_wl.append(w)
        else:                        
            if bang_wl:
                out_wl.append(','.join(bang_wl))
                bang_wl = []
            out_wl.append(w)
    if bang_wl:                               
        out_wl.append(','.join(bang_wl))
    output.append(out_wl)
   ....: 
100000 loops, best of 3: 15.2 µs per loop

In [33]: %%timeit
out = []
>>> for lst in words:
    d = []
    for k, g in groupby(lst, lambda x: '!' in x):
        if k:
            d.append(', '.join(g))
        else:                     
            d.extend(g)
    out.append(d)
   ....: 
10000 loops, best of 3: 48.1 µs per loop

If you just want the words ending with an !:

In [34]: %%timeit
result= []
for sub_lst in words:
    result.append([])
    temp = ""                              
    for ele in sub_lst:
        if not temp andnot ele[-1] == "!":
            result[-1].append(ele)
        elif temp andnot ele[-1] == "!":
            result[-1].append(temp)
            result[-1].append(ele)
            temp = ""
        else:               
            temp += "," + ele if temp else ele
    if temp:                            
        result[-1].append(temp)
   ....: 
100000 loops, best of3: 17 µs per loop

Post a Comment for "Combine Elements Of Lists If Some Condition"