Combine elements of lists if some condition

后端 未结 3 1734
一生所求
一生所求 2021-01-18 00:06

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.

相关标签:
3条回答
  • 2021-01-18 00:46

    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!']]
    
    0 讨论(0)
  • 2021-01-18 00:47
    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 and not ele[-1] == "!":
                result[-1].append(ele)
            elif temp and not 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 of 3: 17 µs per loop
    
    0 讨论(0)
  • 2021-01-18 00:54

    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.

    0 讨论(0)
提交回复
热议问题