2017-01-26 3 views
1

適切な順序で繰り返し要素を持つリストを印刷するには:以下はPythonスクリプトは、リストからユニークな要素を削除し、私は繰り返し要素を持つリストをリストからすべてのユニークな要素を削除し、印刷するには、スクリプトを書いた

入力リストの出力リストはどのようにするべきでしょうか?

Input list1: 
1,2,1,1,3,5,3,4,3,1,6,7,8,5 

Output List1: 
1,1,1,3,5,3,3,1,5 

Input list2: 
1,2,1,1,3,3,4,3,1,6,5 

Output List2: 
1,1,1,3,3,3,1 

#! /bin/python 

def remove_unique(*n): 
    dict1={} 
    list1=[] 
    for i in range(len(n)): 
     for j in range(i+1,len(n)): 
      if n[i] == n[j]: 
       dict1[j]=n[j] 
       dict1[i]=n[i] 
    for x in range(len(n)): 
     if x in dict1.keys(): 
      list1.append(dict1[x]) 
    return list1 

lst1=remove_unique(1,2,1,1,3,5,3,4,3,1,6,7,8,5) 
for n in lst1: 
    print(n, end=" ") 

上記のスクリプトは、いくつかの小さなリストでテストしたときに期待どおりに動作します。しかし、私は(< 50000 = LEN(リスト)< = 50M)より大きな長さの入力リストの(両方の時間と空間の複雑さを考慮)スクリプトを最適化する方法についていくつかのアイデアをしたい

+0

Jean-Françoisはこの問題を効率的に解決してくれましたが、将来参照するには、dict1のxがdict1.keys()のxよりも優れています。 '.keys()'はディクショナリ上で[View object](https://docs.python.org/3/library/stdtypes.html#dict-views)を返しますが、Python 2では返すので、Python 3では許容されますそれはdictをスキャンしてキーのリストを作成しなければならないので悪いことです。そして 'in'テストを実行するために' .keys() 'リストのリニアスキャンを行わなければなりません。また、 'for x in range(len(n)):'ループの_every_繰り返しでそのリストを構築することは、非常に効率的ではありません。 –

答えて

3

スクリプトは、多くの問題があります。

ループ、ないようパフォーマンスで append
  • 古典if x in dict1.keys() =>if x in dict1ではなく
  • リニアなしリスト内包の辞書チェックを使用してくださいします。なぜなら、二重ループの
  • O(n^2)複雑

私のアプローチ:

あなたはocurrencesの数のフィルタを使用して、リストの内包表記を使用して、新しいリストをフィルタリング、その後、collections.Counterを使用して要素を数えることができます。

from collections import Counter 

list1 = [1,2,1,1,3,5,3,4,3,1,6,7,8,5] 

c = Counter(list1) 
new_list1 = [k for k in list1 if c[k]>1] 

print(new_list1) 

結果:

[1, 1, 1, 3, 5, 3, 3, 1, 5] 

私は間違っているかもしれませんが、このアプローチの複雑さは、(およそ)O(n*log(n))(リストのリニアスキャンとディクショナリのキーのハッシングとリストの理解のルックアップです)です。だから、それは良いパフォーマンス賢明です。

+0

ファブレ:解説をありがとう –

関連する問題