web-dev-qa-db-ja.com

順序集合として順序辞書を使用する

Python 3.7が順序を維持する辞書を作成する 正式には言語仕様の一部 実装の詳細ではなく、私は頭を包み込むように努めてきましたこのプロパティを使用します。今日、順序を保持するセットが必要であることがわかり、辞書でうまくいくと思います。

ハッシュ可能な要素のリストがあるとします。一意のエントリのリストが必要であり、最初の出現に基づいてこれらのエントリの順序を維持する必要があります。単純な辞書コンストラクターでうまくいくはずです。

ls = "Beautiful is better than ugly. Explicit..."
uniques = list({s:0 for s in ls})

>>> ['B', 'e', 'a', 'u', 't', 'i', 'f', 'l', ' ', 's', 'b', 'r', 'h', 'n', 'g', 'y', '.', 'E', 'x', 'p', 'c']

これにより、最初の出現による順序が保持され、すべての重複が削除されます。

コミュニティがこのユースケースと一般的な注文保存機能についてどのように考えているか知りたいです。

  • この方法を使用すべきでない理由はありますか?
  • この問題を解決するためのより良い方法はありますか?
  • このメソッドはPythonicですか?

PythonのZenを読んで、私は対立しています。この方法は単純ですが、暗黙の順序に依存しています。

ご意見をお聞かせください。ありがとうございました。

10

Python 3.7ディクショナリを順序を保持する重複排除として使用するこのアプローチは、コアPython開発者 ここ によって精査されています。それ以上の推奨はありません。

この方法を使用すべきでない理由はありますか?

番号。

この問題を解決するためのより良い方法はありますか?

番号。

このメソッドはPythonicですか?

はい。

この方法は単純ですが、暗黙の順序に依存しています。

あなたの質問はpython-3.7のタグが付けられています。挿入順序を保持する辞書が保証されているため、ここでは暗黙的な順序はありません。

7
wim

これはPython 3.7!..でうまく機能しますが、Python 3.7だけがPythonバージョンではありません。コードが3.6より前のPythonバージョンで実行されると、完全にサイレントに順序の維持が停止するため、dictの順序の保持はかなり長い間危険な習慣になります。

たとえば、dataclassesまたはcontextvarsに依存することは、それほど危険ではありません。dataclassesに依存するコードをPythonで、dataclassesがない場合、大きな値になるためです。 、clear ImportError。順序を失ったディクトは、同じように明白ではありません。

あなたはそれが秩序を維持するのをやめたとは思わないかもしれません。 dictの順序に依存したことを覚えていないかもしれません。文書化するのを忘れたり、信頼していることを誰かに伝えたりすることを忘れたり、Python 3.7 + 3.7 +の要件を文書化せずに他の誰かがdictの順序に依存したコードを継承する貧弱なコーダーかもしれません。ある特定のマシンでPythonを更新するのを忘れた、または誤ってAnacondaなどから脱落し、システムを使用しているPython 3それはまだ3.4を使用しています。

最終的にはdictの順序を想定しても安全です。今のところ、特に、3.7のリリースから数日後は、OrderedDictを使用するか、バージョンチェックを追加することをお勧めします。

import collections
import sys

_make_ordered_mapping = (dict.fromkeys if sys.version_info >= (3, 7)
                         else collections.OrderedDict.fromkeys)

def ordered_dedup(items):
    return list(_make_ordered_mapping(items))