简体   繁体   中英

Optimizing a merge sort function in python

Any ideas to optimize this merge sort function?

The input is a list like this: [[(1,'i'),(3,'i'),(5,'i'),(8,'i')], [(2,'n')], [(4,'t'),(7,'t')], [(6,'a')], [(9,'v')],[(10,'e')]], and output is the word: "initiative"

def merge(decks):
    while len(decks) > 1:
        del1 = decks.pop(0)
        del2 = decks.pop(0)
        total = list()
        while (len(del1) and len(del2)) > 0:
            if del1[0] < del2[0]:
                total.append(del1.pop(0))
            else:
                total.append(del2.pop(0))
        total.extend(del1)
        total.extend(del2)
        decks.append(total)

    word = ""
    for kort in decks[0]:
        word += kort[1]
    return word

There's one optimization I can think of: Reverse both del[0] and del[1] before the inner loop and change list.pop(0) ( an O(n) operation ) to list.pop() (which is in O(1)). Reversing is also O(n), but since you do the pop(0) ing inside the loop, it's actually O(n^2) .

Far simpler is to simply flatten the list, then sort the tuples naturally.

from itertools import chain, imap
from operator import itemgetter 

def merge(decks):
    return "".join(imap(itemgetter(1),
                   sorted(chain.from_iterable(decks)))
  • from_iterable flattens the nested list
  • sorted sorts the tuples in the flattened sequence naturally, by the integer first element of each tuple
  • itemgetter(1) is an efficient implementation of lambda x: x[1]
  • imap applies the access function to the list returned by sorted , extracting the letters
  • "".join builds a new string from the extracted letters

Slightly less "functional" in style would be to use a list comprehension, which makes sense because sorted returns a list anyway, instead of a more general iterator.

def merge(decks):
    return "".join(x[1]
                   for x in sorted(chain.from_iterable(decks)))

You could also use the heapq module's merge function, which takes advantage of the fact that each nested list is already sorted, rather than simply sorting the flattened list.

import heapq
def merge(decks):
    return "".join(x[1] for x in heapq.merge(*decks))

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