简体   繁体   中英

Is there a better way to combine multiple items in a python list

I've created a function to combine specific items in a python list, but I suspect there is a better way I can't find despite extreme googling. I need the code to be fast, as I'm going to be doing this thousands of times.

mergeleft takes a list of items and a list of indices. In the example below, I call it as mergeleft(fields,(2,4,5)). Items 5, 4, and 2 of list fields will be concatenated to the item immediately to the left. In this case, 3 and d get concatenated to c ; b gets concatenated to a . The result is a list ('ab', 'cd3', 'f').

fields = ['a','b','c','d', 3,'f']

def mergeleft(x, fieldnums):
    if 1 in fieldnums: raise Exception('Cannot merge field 1 left')
    if max(fieldnums) > len(x): raise IndexError('Fieldnum {} exceeds available fields {}'.format(max(fieldnums),len(x)))
    y = []
    deleted_rows = ''

    for i,l in enumerate(reversed(x)):
        if (len(x) - i) in fieldnums:
            deleted_rows = str(l) + deleted_rows
        else:
            y.append(str(l)+deleted_rows)
            deleted_rows = ''

    y.reverse()
    return y

print(mergeleft(fields,(2,4,5)))
# Returns ['ab','cd3','f']
fields = ['a','b','c','d', 3,'f']

This assumes a list of indices in monotonic ascending order. I reverse the order, so that I'm merging right-to-left. For each given index, I merge that element into the one on the left, converting to string at each point. Do note that I've changed the fieldnums type to list, so that it's easily reversible. You can also just traverse the tuple in reverse order.

def mergeleft(lst, fieldnums):
    fieldnums.reverse()
    for pos in fieldnums:
        # Merge this field left
        lst[pos-2] = str(lst[pos-2]) + str(lst[pos-1])
        lst = lst[:pos-1] + lst[pos:]

    return lst

print(mergeleft(fields,[2,4,5]))

Output:

['ab', 'cd3', 'f']

Here's a decently concise solution, probably among many.

def mergeleft(x, fieldnums):
    if 1 in fieldnums: raise Exception('Cannot merge field 1 left')
    if max(fieldnums) > len(x): raise IndexError('Fieldnum {} exceeds available fields {}'.format(max(fieldnums),len(x)))
    ret = list(x)
    for i in reversed(sorted(set(fieldnums))):
        ret[i-1] = str(ret[i-1]) + str(ret.pop(i))
    return ret

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