0

Python 2.7 のセットに関するチュートリアルに取り組んでいますが、理解できないループを使用する動作に遭遇forしました。出力の違いの理由を突き止めようとしています。

この演習の目的は、for ループを使用して、凍結されたセットの都市のペアで構成されるキーを含む辞書から、セットの都市を生成することです。

データは次の辞書から取得されます。

flight_distances = {
    frozenset(['Atlanta', 'Chicago']): 590.0,
    frozenset(['Atlanta', 'Dallas']): 720.0,
    frozenset(['Atlanta', 'Houston']): 700.0,
    frozenset(['Atlanta', 'New York']): 750.0,
    frozenset(['Austin', 'Dallas']): 180.0,
    frozenset(['Austin', 'Houston']): 150.0,
    frozenset(['Boston', 'Chicago']): 850.0,
    frozenset(['Boston', 'Miami']): 1260.0,
    frozenset(['Boston', 'New York']): 190.0,
    frozenset(['Chicago', 'Denver']): 920.0,
    frozenset(['Chicago', 'Houston']): 940.0,
    frozenset(['Chicago', 'Los Angeles']): 1740.0,
    frozenset(['Chicago', 'New York']): 710.0,
    frozenset(['Chicago', 'Seattle']): 1730.0,
    frozenset(['Dallas', 'Denver']): 660.0,
    frozenset(['Dallas', 'Los Angeles']): 1240.0,
    frozenset(['Dallas', 'New York']): 1370.0,
    frozenset(['Denver', 'Los Angeles']): 830.0,
    frozenset(['Denver', 'New York']): 1630.0,
    frozenset(['Denver', 'Seattle']): 1020.0,
    frozenset(['Houston', 'Los Angeles']): 1370.0,
    frozenset(['Houston', 'Miami']): 970.0,
    frozenset(['Houston', 'San Francisco']): 1640.0,
    frozenset(['Los Angeles', 'New York']): 2450.0,
    frozenset(['Los Angeles', 'San Francisco']): 350.0,
    frozenset(['Los Angeles', 'Seattle']): 960.0,
    frozenset(['Miami', 'New York']): 1090.0,
    frozenset(['New York', 'San Francisco']): 2570.0,
    frozenset(['San Francisco', 'Seattle']): 680.0,
}

チェックとして目的のセットを作成するテスト リストもあります。

flying_circus_cities = [
    'Houston', 'Chicago', 'Miami', 'Boston', 'Dallas', 'Denver', 
    'New York', 'Los Angeles', 'San Francisco', 'Atlanta', 
    'Seattle', 'Austin'
]

コードが次の形式で記述されている場合、ループは意図した結果を生成します。

cities = set()
for pair in flight_distances:
    cities = cities.union(pair)
print cities
print "Check:", cities == set(flying_circus_cities)

出力:

set(['Houston', 'Chicago', 'Miami', 'Boston', 'Dallas', 'Denver', 'New York', 'Los Angeles', 'San Francisco', 'Atlanta', 'Seattle', 'Austin'])
Check: True

ただし、次のいずれかで理解しようとすると、別の結果が得られます。

cities = set()
cities = {pair for pair in flight_distances}
print cities
print "Check:", cites == set(flying_circus_cities)

また

cities = set()
cities = cities.union(pair for pair in flight_distances)
print cities
print "Check:", cities == set(flying_circus_cities)

両方の出力:

set([frozenset(['Atlanta', 'Dallas']), frozenset(['San Francisco', 'New York']), frozenset(['Denver', 'Chicago']), frozenset(['Houston', 'San Francisco']), frozenset(['San Francisco', 'Austin']), frozenset(['Seattle', 'Los Angeles']), frozenset(['Boston', 'New York']), frozenset(['Houston', 'Atlanta']), frozenset(['New York', 'Chicago']), frozenset(['San Francisco', 'Seattle']), frozenset(['Austin', 'Dallas']), frozenset(['New York', 'Dallas']), frozenset(['Houston', 'Chicago']), frozenset(['Seattle', 'Denver']), frozenset(['Seattle', 'Chicago']), frozenset(['Miami', 'New York']), frozenset(['Los Angeles', 'Denver']), frozenset(['Miami', 'Houston']), frozenset(['San Francisco', 'Los Angeles']), frozenset(['New York', 'Denver']), frozenset(['Atlanta', 'Chicago']), frozenset(['Boston', 'Chicago']), frozenset(['Houston', 'Austin']), frozenset(['Houston', 'Los Angeles']), frozenset(['New York', 'Los Angeles']), frozenset(['Atlanta', 'New York']), frozenset(['Denver', 'Dallas']), frozenset(['Los Angeles', 'Dallas']), frozenset(['Los Angeles', 'Chicago'])])
Check: False

最初の例の for ループが意図したとおりにペアをアンパックして、各都市の 1 つのインスタンスを含むセットを生成する理由がわかりませんが、内包としてループを記述しようとすると、ペアが引き出され、frozenset([city1, city2])代わりにセットに配置されます。 .

pair最初のインスタンスで都市の文字列を与えるのに、2番目のインスタンスでfrozensetを渡す理由がわかりません。

誰かが異なる動作を説明できますか?

注: Holtdonkopotamusによって説明されているように、これが異なる動作をする理由の問題は、内包表記を使用すると、cities変数への単一の割り当てを行う前に辞書全体が完全に評価されたため、標準forループが展開されたときに一連の凍結セットが作成されたためです。ペアを一度に 1 つずつ個別に評価しcities、ループの各パスで一度に 1 つずつ割り当てfor、union 関数が渡されたペアの各インスタンスを評価できるようにします。

彼らはさらに、 - 演算子を使用すると、*内包表記で辞書がアンパックされ、目的の動作が生成されると説明しました。

cities = cities.union(*(set(pair) for pair in flight_distances))
4

2 に答える 2

1

表現:

cities = set()
cities = cities.union(pair for pair in flight_distances)

空集合{}と別の集合との結合を取ります

{pair_0, pair_1, pair_2, ..., pair_n}

セットのセットを残します。

対照的に、次の例では、飛行先のすべての都市が表示されます。

>>> set.union(*(set(pair) for pair in flight_distances))
{'Atlanta',
 'Austin',
 'Boston',
 'Chicago',
 'Dallas',
 'Denver',
 'Houston',
 'Los Angeles',
 'Miami',
 'New York',
 'San Francisco',
 'Seattle'}

ここでは、固定されたセット キーのそれぞれをプレーン セットに変換し、和集合を見つけます。

于 2016-06-27T08:55:17.677 に答える
0

最初のバージョンでpairfrozensetat each ループなので、それを使用して aunionを実行できますが、あなたのバージョンでは、setofを使用してユニオンを実行しようとしますfrozenset

最初のケースは (frozenset各反復で a との結合) になります。

cities = set()
cities.union(frozenset(['Atlanta', 'Chicago']))
cities.union(frozenset(['Atlanta', 'Dallas']))
...

したがって、(数学的に)次のようになります。

cities = {} # Empty set
cities = {} U {'Atlanta', 'Chicago'} = {'Atlanta', 'Chicago'}
cities = {'Atlanta', 'Chicago'} U {'Atlanta', 'Dallas'} = {'Atlanta', 'Chicago', 'Dallas'}
...

あなたの(最後の)ケースでは、次のことを行っています( のシーケンスを持つ1つのユニオンfrozenset):

cities = set()
cities.union([frozenset(['Atlanta', 'Chicago']), frozenset(['Atlanta', 'Dallas']), ...])

だからあなたは持っています:

cities = {}
cities = {} U {{'Atlanta', 'Chicago'}, {'Atlanta', 'Dallas'}, ...} 
       = {{'Atlanta', 'Chicago'}, {'Atlanta', 'Dallas'}, ...} # Nothing disappears

同一のペアは 2 つとないため、最初のディクショナリ内のすべてのペアのセットを取得します。これは、都市の ではなく、都市の (ペア) を に渡しているsetためsetです。set.union()


より抽象的な観点から、取得しようとしているものは次のとおりです。

S = {} U S1 U S2 U S3 U ... U Sn = (((({} U S1) U S2) U S3) U ...) U Sn

と:

S = {} U {S1, S2, S3, ..., Sn}
于 2016-06-27T08:58:56.687 に答える