2017-12-01 9 views
-5

のリストを転置するための効率的な方法:私はリストのリストを持っているリスト

私はに変換する必要があり
x = [ [4, ‘c’, ‘b’, ‘d’], [2, ‘e’, ‘c’, ‘a’], [5, ‘a’, ‘c’] ] 

x1 = [ [‘c’, 4, 2, 5], [‘b’, 4], [‘d’, 4], [‘e’, 2], [‘a’, 2, 5] ] 

説明:明らかに

'c' appears in lists starting with 4, 2, 5 
'b' appears in only the list starting with 4 
'd' appears in only the list starting with 4 
... 

これはおもちゃの例ですが、私の実際のリストはフラットファイルで約30Mbです。

私は2つの入れ子になったfor-loopsで試していましたが、MacBook Pro(8GB RAM)のファイルの5%だけで約5時間かかりました。

効率的な方法はありますか?

+0

はあなたが試みを試みたがありますか?助けを求める前に何かを試してみないと – depperm

+0

xをx1に変換するために使用されているロジックに従うことができず、ランダムに見えます。 – sniperd

+0

私はここでパターンを見つけることさえできません。 '2'はなぜ入力に1回だけ出現しますが、出力には3回出現するのですか? '4'と同じですが、' 5'は2回しか出現しません。 –

答えて

3

私は2つのネストされたループでそれをも管理している:

from collections import defaultdict 

x = [ [4, 'c', 'b', 'd'], [2, 'e', 'c', 'a'], [5, 'a', 'c'] ] 

d = defaultdict(list) 

for group in x: 
    key = group[0] 
    for item in group[1:]: 
     d[item].append(key) 


print(d) 

# and to convert back to list: 
x1 = [[key]+value for (key,value) in d.items()] 
print(x1) 

出力:効率の

defaultdict(<class 'list'>, {'c': [4, 2, 5], 'b': [4], 'd': [4], 'e': [2], 'a': [2, 5]}) 
[['c', 4, 2, 5], ['b', 4], ['d', 4], ['e', 2], ['a', 2, 5]] 

注:

外側のループの内側には、私はgroup[1:]を計算。今、groupが大きい場合、リストをコピーするだけでも高価になることがあります。ループは、このように良いかもしれないその場合:

for group in x: 
    it = iter(group) 
    key = next(it) 
    for item in it: 
     d[item].append(key) 

効率、そして、nは、すべてのリスト内の項目の合計数ですO(n)です。この処理、または30MBのファイルコンテンツの読み込みが最も遅いかどうか、私は測定できません。あなたが実際に達成するために何をしたいの@のquamranaの仮定に基づいて

+0

あなたの最後のアプローチが最も速い解決策でした。最初の時間よりも約15%の時間がかかりました。ありがとう。 –

1

x = [ [4, 'c', 'b', 'd'], 
     [2, 'e', 'c', 'a'], 
     [5, 'a', 'c'] ] 

letters = {i for y in x for i in y if isinstance(i, str)} 
y = [[i] + [sub[0] for sub in x if i in sub] for i in letters] 
print(y) # [['e', 2], ['d', 4], ['a', 2, 5], ['b', 4], ['c', 4, 2, 5]] 
関連する問題