2017-08-29 7 views
0

このマージソート関数を最適化する方法はありますか?Pythonのマージソート関数を最適化する

入力は次のようなリストです:[[(1、 'i')、(3、 'i')、(5、 'i')、(8、 'i')]、[ (9、 'v')]、[(10、 'n')]、[(4、 't')、 『イニシアチブ』

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 
+4

'(LEN(DEL1)とlen(DEL2))> :) –

+0

あなたには、いくつかの小さな最適化を実行できますが、これは上のトピックのhttpのためのより多くのです://コードレビュー。 stackexchange.com –

+0

@ Jean-FrançoisFabre何を意味していますか? –

答えて

0

私は考えることができる1つの最適化があります:内部ループの前del[0]del[1]の両方を逆にしてlist.pop(0)an O(n) operationを変更)list.pop()に(これはE ')]]、および出力が単語でありますO(1)に)。反転もO(n)ですが、ループ内でpop(0)を実行するので、実際にはO(n^2)です。

+0

なぜでしょうか'pop(0)'は 'O(n)'と 'pop()'を持っていませんか? popのC実装にはループがありません –

+2

'list.pop'メソッドは正面からポップ(' pop(0) ')したときに' O(n) 'メソッドです。これは、ポップされた値が削除された後に削除されるまで移動する必要があるからです。これは '' list'_ass_slice'(https://github.com/python/cpython/blob/631fdee6e61b4ba8ce800f827fecdd536bfb04f3/Objects/listobject.c#L580)で起こります。これは 'pop'実装によって呼び出されます。その関数にはいくつかのループがありますが、特に気にするのは、654行目の 'memmove'呼び出しです。これはリストのすべての値を1つのスペースにコピーします。おそらく、コンパイラによって最適化されていますが、それでも 'O(n)'です。 – Blckknght

+0

Python wikiの[TimeComplexity](https://wiki.python.org/moin/TimeComplexity)を参照してください。 – L3viathan

0

単純にリストを平坦化してから、タプルを自然にソートするだけです。

from itertools import chain, imap 
from operator import itemgetter 

def merge(decks): 
    return "".join(imap(itemgetter(1), 
        sorted(chain.from_iterable(decks))) 
  • from_iterable各タプル
  • itemgetter(1)の整数最初の要素は、lambda x: x[1]
  • imap適用の効率的な実装であることにより、ネストされたリスト
  • sortedは、自然に平坦化シーケンス内のタプルをソート平坦化sortedによって返されたリストへのアクセス関数は、文字を抽出する
  • "".joinは少し少ない「機能的」なスタイルで抽出された文字

から新しい文字列を構築しますsortedではなく、より一般的なイテレータの、とにかくリストを返すので、理にかなって、リストの内包表記を使用することです。

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

はまた、各ネストされたリストは、既に単純に平らにリストをソートするのではなく、ソートされているという事実を利用するheapqモジュールのmerge機能を、使用することができます。ところで全くの運で働く0 '

import heapq 
def merge(decks): 
    return "".join(x[1] for x in heapq.merge(*decks)) 
関連する問題