List 内の辞書が設定されていて、同一の内容の要素の重複を排除しようとして、
set関数を使って重複を排除しようとしたところ、
TypeError: unhashable type: 'dict'いうエラーが発生して、重複の排除ができませんでした。
これは辞書に、ハッシュ関数の実装がないために発生します。

Python における hashable - Qiita


エラーが発生するコードサンプル

key_dimensions = [{'name': 'ga:dimension8'}, {'name': 'ga:dimension10'}]

all_dimensions = [{'name': 'ga:dimension1'},
            {'name': 'ga:dimension2'},
            {'name': 'ga:dimension3'},
            {'name': 'ga:dimension4'},
            {'name': 'ga:dimension5'},
            {'name': 'ga:dimension6'},
            {'name': 'ga:dimension7'},
            {'name': 'ga:dimension8'},
            {'name': 'ga:dimension9'},
            {'name': 'ga:dimension10'},
            {'name': 'ga:dimension11'},
            {'name': 'ga:dimension12'},
            {'name': 'ga:dimension13'},
            {'name': 'ga:dimension14'},
            {'name': 'ga:dimension15'},
            {'name': 'ga:dimension16'},
            {'name': 'ga:dimension17'},
            {'name': 'ga:dimension18'},
            {'name': 'ga:dimension19'},
            {'name': 'ga:dimension20'}]

key_dimensions.extend(all_dimensions)
key_dimensions

set(key_dimensions)

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-7-f57935d1d554> in <module>
----> 1 set(key_dimensions)


TypeError: unhashable type: 'dict'

hashable な辞書

frozendict · PyPI使うと、hashbaleな辞書を作ることができます。

!pip3 install frozendict

Collecting frozendict
  Using cached https://files.pythonhosted.org/packages/4e/55/a12ded2c426a4d2bee73f88304c9c08ebbdbadb82569ebdd6a0c007cfd08/frozendict-1.2.tar.gz
Building wheels for collected packages: frozendict
  Running setup.py bdist_wheel for frozendict ... [?25ldone
[?25h  Stored in directory: /Users/kensakurai/Library/Caches/pip/wheels/6c/6c/e9/534386165bd12cf1885582c75eb6d0ffcb321b65c23fe0f834
Successfully built frozendict
Installing collected packages: frozendict
Successfully installed frozendict-1.2

from frozendict import frozendict

key_dimensions = [{'name': 'ga:dimension8'}, {'name': 'ga:dimension10'}]
all_dimensions = [{'name': 'ga:dimension1'},
            {'name': 'ga:dimension2'},
            {'name': 'ga:dimension3'},
            {'name': 'ga:dimension4'},
            {'name': 'ga:dimension5'},
            {'name': 'ga:dimension6'},
            {'name': 'ga:dimension7'},
            {'name': 'ga:dimension8'},
            {'name': 'ga:dimension9'},
            {'name': 'ga:dimension10'},
            {'name': 'ga:dimension11'},
            {'name': 'ga:dimension12'},
            {'name': 'ga:dimension13'},
            {'name': 'ga:dimension14'},
            {'name': 'ga:dimension15'},
            {'name': 'ga:dimension16'},
            {'name': 'ga:dimension17'},
            {'name': 'ga:dimension18'},
            {'name': 'ga:dimension19'},
            {'name': 'ga:dimension20'}]

key_dimensions = [frozendict(elem) for elem in key_dimensions]
all_dimensions = [frozendict(elem) for elem in all_dimensions]

key_dimensions.extend(all_dimensions)
key_dimensions

[<frozendict {'name': 'ga:dimension8'}>,
 <frozendict {'name': 'ga:dimension10'}>,
 <frozendict {'name': 'ga:dimension1'}>,
 <frozendict {'name': 'ga:dimension2'}>,
 <frozendict {'name': 'ga:dimension3'}>,
 <frozendict {'name': 'ga:dimension4'}>,
 <frozendict {'name': 'ga:dimension5'}>,
 <frozendict {'name': 'ga:dimension6'}>,
 <frozendict {'name': 'ga:dimension7'}>,
 <frozendict {'name': 'ga:dimension8'}>,
 <frozendict {'name': 'ga:dimension9'}>,
 <frozendict {'name': 'ga:dimension10'}>,
 <frozendict {'name': 'ga:dimension11'}>,
 <frozendict {'name': 'ga:dimension12'}>,
 <frozendict {'name': 'ga:dimension13'}>,
 <frozendict {'name': 'ga:dimension14'}>,
 <frozendict {'name': 'ga:dimension15'}>,
 <frozendict {'name': 'ga:dimension16'}>,
 <frozendict {'name': 'ga:dimension17'}>,
 <frozendict {'name': 'ga:dimension18'}>,
 <frozendict {'name': 'ga:dimension19'}>,
 <frozendict {'name': 'ga:dimension20'}>]

set(key_dimensions)

{<frozendict {'name': 'ga:dimension1'}>,
 <frozendict {'name': 'ga:dimension10'}>,
 <frozendict {'name': 'ga:dimension11'}>,
 <frozendict {'name': 'ga:dimension12'}>,
 <frozendict {'name': 'ga:dimension13'}>,
 <frozendict {'name': 'ga:dimension14'}>,
 <frozendict {'name': 'ga:dimension15'}>,
 <frozendict {'name': 'ga:dimension16'}>,
 <frozendict {'name': 'ga:dimension17'}>,
 <frozendict {'name': 'ga:dimension18'}>,
 <frozendict {'name': 'ga:dimension19'}>,
 <frozendict {'name': 'ga:dimension2'}>,
 <frozendict {'name': 'ga:dimension20'}>,
 <frozendict {'name': 'ga:dimension3'}>,
 <frozendict {'name': 'ga:dimension4'}>,
 <frozendict {'name': 'ga:dimension5'}>,
 <frozendict {'name': 'ga:dimension6'}>,
 <frozendict {'name': 'ga:dimension7'}>,
 <frozendict {'name': 'ga:dimension8'}>,
 <frozendict {'name': 'ga:dimension9'}>}

# _dict で辞書が取得できます
key_dimensions[0]._dict

{'name': 'ga:dimension8'}

#  _hashでhash値が取得できます
key_dimensions[0]._hash

-5282691924994355217

# get(key名)でVlaue値が取得できます。
key_dimensions[0].get("name")

'ga:dimension8'

List内包表記で重複を排除する

frozendict 辞書 ではないので、辞書を引数にとるメソッド呼び出し前のデータ加工時は特に役に立たないかもしれません。
Stack Overflow の記事に List 内包表記で重複を排除するサンプルが記載されていて、それが個人的にいい感じに思いましたので、記載します。

key_dimensions = [{'name': 'ga:dimension8'}, {'name': 'ga:dimension10'}]

all_dimensions = [{'name': 'ga:dimension1'},
            {'name': 'ga:dimension2'},
            {'name': 'ga:dimension3'},
            {'name': 'ga:dimension4'},
            {'name': 'ga:dimension5'},
            {'name': 'ga:dimension6'},
            {'name': 'ga:dimension7'},
            {'name': 'ga:dimension8'},
            {'name': 'ga:dimension9'},
            {'name': 'ga:dimension10'},
            {'name': 'ga:dimension11'},
            {'name': 'ga:dimension12'},
            {'name': 'ga:dimension13'},
            {'name': 'ga:dimension14'},
            {'name': 'ga:dimension15'},
            {'name': 'ga:dimension16'},
            {'name': 'ga:dimension17'},
            {'name': 'ga:dimension18'},
            {'name': 'ga:dimension19'},
            {'name': 'ga:dimension20'}]
key_dimensions.extend(all_dimensions)
[dict(s) for s in set(frozenset(d.items()) for d in key_dimensions)]

[{'name': 'ga:dimension6'},
 {'name': 'ga:dimension8'},
 {'name': 'ga:dimension20'},
 {'name': 'ga:dimension9'},
 {'name': 'ga:dimension11'},
 {'name': 'ga:dimension13'},
 {'name': 'ga:dimension12'},
 {'name': 'ga:dimension18'},
 {'name': 'ga:dimension16'},
 {'name': 'ga:dimension1'},
 {'name': 'ga:dimension19'},
 {'name': 'ga:dimension17'},
 {'name': 'ga:dimension15'},
 {'name': 'ga:dimension10'},
 {'name': 'ga:dimension4'},
 {'name': 'ga:dimension14'},
 {'name': 'ga:dimension2'},
 {'name': 'ga:dimension5'},
 {'name': 'ga:dimension3'},
 {'name': 'ga:dimension7'}]

参考

以上です。

コメント