简体   繁体   English

在python中优化合并排序功能

[英]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" 输入是一个像这样的列表:[[((1,'i'),(3,'i'),(5,'i'),(8,'i')]],[(2,'n' )],[(4,'t'),(7,'t')],[(6,'a')],[(9,'v')],[(10,'e')] ],然后输出单词:“ 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)). 我可以想到一个优化:在内部循环之前反转del[0]del[1]并将list.pop(0)一个O(n)操作 )更改为list.pop() (在O中(1))。 Reversing is also O(n), but since you do the pop(0) ing inside the loop, it's actually O(n^2) . 反转也是O(n),但是由于您在循环内执行pop(0) ,所以实际上是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 from_iterable平嵌套列表
  • sorted sorts the tuples in the flattened sequence naturally, by the integer first element of each tuple sorted每个元组的整数first元素自然地对展平序列中的元组sorted排序
  • itemgetter(1) is an efficient implementation of lambda x: x[1] itemgetter(1)lambda x: x[1]的有效实现lambda x: x[1]
  • imap applies the access function to the list returned by sorted , extracting the letters imap将访问功能应用于sorted返回的列表,提取字母
  • "".join builds a new string from the extracted letters "".join从提取的字母中构建一个新的字符串

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. 风格上“功能性”稍差一点的是使用列表理解,这很有意义,因为sorted无论如何都会返回一个列表,而不是更通用的迭代器。

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. 您还可以使用heapq模块的merge函数,该函数利用了每个嵌套列表都已排序的事实,而不是简单地对扁平化列表进行排序。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM