2016-04-22 13 views
2

私は辞書の2つのリストの違いを見つけることを試みています。私はこのフォーラムでいくつかの情報を見つけましたが、私の目的には役立ちませんでした。私のテーブル名が一意であるformat.Here私は辞書との違いのavailable_rowリストでincoming_rowsを比較する必要がPythonの辞書の2つのリストの違いを見つける

ここ
incoming_rows = [{'column_name': 'LOAD_ID', 'data_type': 'int', 'table_name': 'CONFIG'}, 
      {'column_name': 'ROW_NUMBER', 'data_type': 'int', 'table_name': 'CONFIG'}, 
      {'column_name': 'CREATE_DATE', 'data_type': 'VARCHAR(20)', 'table_name': 'CONFIG'}, 
      {'column_name': 'CONFIG_TYPE', 'data_type': 'varchar(1)', 'table_name': 'CONFIG'}, 
      {'column_name': 'CONFIG_ID', 'data_type': 'numeric(10,0)', 'table_name': 'CONFIG'} 
      ] 

available_row = [{'column_name': 'LOAD_ID', 'data_type': 'int', 'table_name': 'CONFIG'}, 
      {'column_name': 'ROW_NUMBER', 'data_type': 'int', 'table_name': 'CONFIG'}, 
      {'column_name': 'CREATE_DATE', 'data_type': 'date', 'table_name': 'CONFIG'} 
      ] 

は、辞書の別のリストに一覧表示します。 条件: 1.新しい列の追加。 2.データ型の変更 これらの2つの条件が真の場合、expected_rowには変更された行のみが含まれている必要があります。

# expected output 
expected_row=[{'column_name': 'CONFIG_TYPE', 'data_type': 'varchar(1)', 'table_name': 'CONFIG'}, 
      {'column_name': 'CONFIG_ID', 'data_type': 'numeric(10,0)', 'table_name': 'CONFIG'}, 
      {'column_name': 'CREATE_DATE', 'data_type': 'VARCHAR(20)', 'table_name': 'CONFIG'} 
     ] 
+0

2リストとの交点を見つけます。これは助けになるかもしれません:http://stackoverflow.com/questions/642763/python-intersection-of-two-lists –

+0

@csessh私たちはリストの交差点を見つけようとしているので* unhashableなオブジェクト*でいっぱいですほとんど無関係です。 (例えば "set()。add({" some ":" dict "})') ') –

答えて

3

セットは、この問題のための完璧なソリューションです。残念ながら、Pythonでは辞書に辞書を追加することはできません。なぜなら、それらは変更可能であり、そのハッシュコードは挿入と参照の間で変更される可能性があるからです。

項目を固定して不変にすると、リストの代わりにオブジェクトを設定することができます。その後、マイナス演算子を使用して差集合を取る:

In [20]: i_set = { frozenset(row.items()) for row in incoming_rows } 

In [21]: a_set = { frozenset(row.items()) for row in available_row } 

In [22]: (i_set - a_set) 
Out[22]: 
{frozenset({('column_name', 'CONFIG_ID'), 
      ('data_type', 'numeric(10,0)'), 
      ('table_name', 'CONFIG')}), 
frozenset({('column_name', 'CREATE_DATE'), 
      ('data_type', 'VARCHAR(20)'), 
      ('table_name', 'CONFIG')}), 
frozenset({('column_name', 'CONFIG_TYPE'), 
      ('data_type', 'varchar(1)'), 
      ('table_name', 'CONFIG')})} 

は編集:アンフリーズする:

In [25]: [dict(i) for i in i_set - a_set] 
Out[25]: 
[{'column_name': 'CONFIG_ID', 
    'data_type': 'numeric(10,0)', 
    'table_name': 'CONFIG'}, 
{'column_name': 'CREATE_DATE', 
    'data_type': 'VARCHAR(20)', 
    'table_name': 'CONFIG'}, 
{'column_name': 'CONFIG_TYPE', 
    'data_type': 'varchar(1)', 
    'table_name': 'CONFIG'}] 
+0

前にアイテムを"フリーズ "したことはありません!それが何であるか少し説明していただけますか?ありがとう! –

+0

frozensetは、Pythonでは不変な型のセットです(例えば、 'frozenset.add(...)'などはできません)。それは不変なので、(sanely)ハッシュ可能なので、セットに入れることができます。 –

+0

これは私が探していたものです。 thanks @ Neal Fultz – Pradeep

-1
for incoming_d, available_d in zip(incoming_rows, available_row): 
    for k,v in incoming_d: 
     if k in available_d and available_d[k] == v: 
      # this key is in both dicts 
     else: 
      # something went wrong 

これは同じ順序であるためにあなたのリストを必要とすることに注意してください。順序がリストに関係ない場合は、あなたが巣に持っていると思いますあなたのforループ(と複雑さが大幅に高くなる)

for incoming_d in incoming_rows: 
    for available_d in available_rows: 
     ... 
関連する問題