2

これはすでに答えられているに違いないと思いましたが、Googleやここでは何も見つかりませんでした.

一般に、Python 辞書の順序に依存できないことは承知しています。ただし、同じキーを持つ 2 つの辞書がある場合、値が同じ順序であることを信頼できますか?

浮動小数点数の2つの辞書を比較しようとしているので、使用できないので質問しますdict1==dict2。私の関数は次のようになります。

def _compare_dict(self, d1, d2):
    """
    Compares two dictionaries of floating point numbers
    for equality.
    """
    if d1.keys() != d2.keys():
        return False

    zipped = zip(d1.itervalues(), d2.itervalues())
    return len(filter(lambda x: abs(x[0] - x[1]) > sys.float_info.epsilon, zipped)) == 0

これは危険なゲームですか?あるテストでは、次の順序が維持されているように見えました。

In [126]: d1={'a': 3, 'b': 2, 'c': 10}
In [127]: d2={'b': 10, 'c': 7, 'a': 2}

In [128]: d1
Out[128]: {'a': 3, 'b': 2, 'c': 10}

In [129]: d2
Out[129]: {'a': 2, 'b': 10, 'c': 7}

しかし、これが信頼できるものかどうかはわかりません。もちろん、浮動小数点数の 2 つの辞書を比較するための他のソリューションも歓迎します。

4

4 に答える 4

8

辞書の作成方法によっては、それに頼ることはできません。

いくつかの例:

>>> a = dict.fromkeys(range(1000))
>>> b = dict.fromkeys(range(500,600))
>>> for i in range(500):
    del a[i]

>>> for i in range(600,1000):
    del a[i]

>>> all(i==j for i,j in zip(a,b))
False
>>> a == b
True

aは、1000 個のオブジェクトにスペースを割り当てているため、はるかに大きなハッシュ テーブルですがb、少し大きくならずに約 100 個しか保持できません。したがって、ハッシュの保存方法によって反復順序が変わる可能性があります

于 2012-07-19T03:28:50.533 に答える
3
def _compare_dict(self, d1, d2):
    """
    Compares two dictionaries of floating point numbers
    for equality.
    """
    if len(d1) != len(d2): # comparing `.keys()` is futile and slow
        return False
    try:
        return all(abs(d1[k] - d2[k]) < sys.float_info.epsilon for k in d1)
    except KeyError:
        return False

あなたがイプシロンについて間違って考えているので、これはそれよりも小さいか大きい数ではまだ機能しません-22

代わりに、意味のあるフロートを比較する方法を選択する必要があります。固定イプシロンを使用することを選択できますが、それはある程度までしか機能しません。フロートは非常に大きくなる可能性があります。

通常、絶対値よりも相対比較を使用する方が適切です。

于 2012-07-19T03:45:15.740 に答える
2

私はこのようなものをお勧めします:

def _compare_dict(self, d1, d2):
    if set(d1.keys()) != set(d2.keys()):
        return False

    for key in d1:
        if abs(d1[key]-d2[key]) > sys.float_info.epsilon:
            return False

    return True

読みやすく、すべての値を比較するのではなく、False範囲内にない2つの値に気付くとすぐに戻ります。sys.float_info.epsilon

于 2012-07-19T03:32:17.310 に答える
1

辞書は順序付けられていません。Python3.3に存在する凍結された辞書を使用しない限り順序付けできません。

ここで、キーを比較するために、キーをセットに変換できます。

a = {'a': 0, 'b': 1}
b = set(a)
c = set(a.keys())  # just another way to be clearer

b == c
True

または、リストを作成して注文して比較することもできます。私はセットアプローチの方が好きです。

于 2012-07-19T03:31:37.793 に答える