2016-08-18 1 views
1

私はデータベースから2つのクエリを実行しています。それぞれから得られる結果は、完全なタプルのリストです。これらをタプルの1つのリストに結合したいと思います。これらは、タプルの例です:2つのタプルのリストを重複なしで結合する方法

list1 = [('abc', 1), ('def', 2) ... ] 
list2 = [(1000, 'abc'), (2000, 'def'), (3000, 'def') ... ] 

私はタプルの一つだけのリストを作成したいと私は、このようにそれらに参加:

q = [] 
for i in list1: 
      for j in list2:   
       if i[0] == (j[1]): 
        i = i + (j[0],) 
        q.append(i) 

私のような何かを得るように、これは私の新しいリストqで重複を返します。これは

q = [('abc', 1 , 1000) , ('def', 2, 2000), ('def', 2, 2000, 3000) ...] 

タプルの2番目のリストのような重複を避けるにはどうすればよいでしょうか? 私はちょうど('def', 2, 2000, 3000)がほしいと思うが、これは('def', 2, 2000), ('def', 2, 2000, 3000)

私はしばらくの間これに固執されているので、何か助けに感謝しています。ありがとう

+0

ネストされたループを使用することは、リストが大きい場合はお勧めできません。詳細は以下を参照してください。 –

答えて

5

ネストされたループを使用することは、リストがかなり小さい場合は大丈夫ですが、大きなリストではすぐに非効率になります。たとえば、len(list1)== 10、len(list2)== 20の場合、内側ループ内のコードは200回実行されます。

ここでは、辞書を使用して希望するタプルのリストを構築するアルゴリズムを示します。辞書はリストに追加することができます。リストに追加することは可能ですがタプルは不変なので、タプルの最後にアイテムを追加するたびにi = i + (j[0],)という新しいタプルオブジェクトが作成されます(同様に一時的な(j[0],)タプル)を削除し、iにバインドされた古いものを破棄します。

list1 = [('abc', 1), ('def', 2), ('ghi', 3)] 
list2 = [ 
    (1000, 'abc'), 
    (2000, 'def'), 
    (2100, 'def'), 
    (3000, 'ghi'), 
    (3100, 'ghi'), 
    (3200, 'ghi'), 
] 

# Insert list1 data into a dict of lists 
d = {t[0]:list(t) for t in list1} 

# Append list2 data to the correct list 
for v, k in list2: 
    d[k].append(v) 

# Convert lists back into tuples, using the key order from list1 
result = [tuple(d[k]) for k, _ in list1] 
for t in result: 
    print(t) 

lenの場合、このアルゴリズムで出力

('abc', 1, 1000) 
('def', 2, 2000, 2100) 
('ghi', 3, 3000, 3100, 3200) 

、(LIST1)== 10とlen(LIST2)== 20は、次に、我々は、辞書を構築するために長さ10のループを有するdリスト2のデータをdのリストに追加する長さ20のループと、長さ10の別のループを使用して、タプルの最終リストを構築します。彼はそれぞれのループ内のステップはかなり基本的で、あなたのi = i + (j[0],)とほぼ同じレベルです。明らかに40ステップは200よりもはるかに優れています。もちろん、入力リストに1000個のアイテムがあれば、私のコードは3000ループになります入れ子になったループのアプローチでは100万回のループが必要です。

list2list1以外のキーが含まれている場合、このコードではKeyErrorが発生します。おそらく、コード(とSevanteri's)はこのような鍵を黙って無視するため、処理しているデータの問題ではないでしょう。 の場合のようなキーを処理する必要がありますが、これはかなり簡単ですが、キーの不一致を処理する必要がなければ、list2ループをより簡単にループ&にすることができます。

+0

詳細な対応をありがとうございます。今すぐリストのサイズは〜20ですが、将来的にはそれは大きくなります。これは長期的にはより良いオプションです – johnfk3

0

内側のループの内側にiを追加する必要はありません。外側ループの終わりにちょうど1回。

q = [] 
for i in list1: 
    for j in list2: 
     if i[0] == j[1]: 
      i = i + (j[0],) 
    q.append(i) 

外部ループにもタイプミスがありました。ちょうどlistの代わりにlist1にする必要があります。

+0

私はタイプミスを編集してくれてありがとう、それは完璧に動作します! – johnfk3

+0

'(j [1])'の前後にある括弧を削除することができます。タプルではなく、単純な値です。 –

+0

@LaurentLAPORTEああ、本当です。そのことに気付かなかった。 :D – Sevanteri

関連する問題