需要帮助理解 for 循环的行为
Need help understanding the behavior of a for loop
我正在学习 Python 2.7 中关于集合的教程,并且我已经 运行 使用了一个我不理解的 for
循环的行为,我正在尝试找出输出差异的原因。
练习的目的是使用 for 循环从包含由冻结集的城市对组成的键的字典中生成一个集 cities。
数据来自以下词典:
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 循环会按预期解包这些对,以便它生成一个包含每个城市的一个实例的集合,同时尝试编写循环作为理解拉出 frozenset([city1, city2])
配对并将它们放在集合中。
我不明白为什么 pair
会在第一个实例中给出城市字符串,但在第二个实例中传递 frozenset。
有人可以解释不同的行为吗?
注意: 正如 Holt and donkopotamus 所解释的那样,为什么这会表现不同的问题是,在对cities
变量,从而创建一组 frozensets,其中标准 for
循环一次解压一对,并分别评估每个个体,一次将它们分配给 cities
一个每次通过 for
循环并允许联合函数评估传递给它的对的每个实例的时间。
他们进一步解释说,使用 *
-operator 在理解中解压字典以产生所需的行为。
cities = cities.union(*(set(pair) for pair in flight_distances))
表达式:
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'}
这里我们将每个冻结集键转换为普通集并找到并集。
在第一个版本中,pair
在每个循环中都是一个 frozenset
,所以你可以用它做一个 union
,而在你的版本中,你尝试做一个联合set
个 frozenset
。
第一种情况归结为(在每次迭代时与 frozenset
合并):
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'}
...
在您的(最后一个)案例中,您正在执行以下操作(一个具有 frozenset
序列的联合):
cities = set()
cities.union([frozenset(['Atlanta', 'Chicago']), frozenset(['Atlanta', 'Dallas']), ...])
所以你有:
cities = {}
cities = {} U {{'Atlanta', 'Chicago'}, {'Atlanta', 'Dallas'}, ...}
= {{'Atlanta', 'Chicago'}, {'Atlanta', 'Dallas'}, ...} # Nothing disappears
因为没有两对是相同的,所以你会得到初始字典中所有对的集合,因为你传递的是 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}
我正在学习 Python 2.7 中关于集合的教程,并且我已经 运行 使用了一个我不理解的 for
循环的行为,我正在尝试找出输出差异的原因。
练习的目的是使用 for 循环从包含由冻结集的城市对组成的键的字典中生成一个集 cities。
数据来自以下词典:
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 循环会按预期解包这些对,以便它生成一个包含每个城市的一个实例的集合,同时尝试编写循环作为理解拉出 frozenset([city1, city2])
配对并将它们放在集合中。
我不明白为什么 pair
会在第一个实例中给出城市字符串,但在第二个实例中传递 frozenset。
有人可以解释不同的行为吗?
注意: 正如 Holt and donkopotamus 所解释的那样,为什么这会表现不同的问题是,在对cities
变量,从而创建一组 frozensets,其中标准 for
循环一次解压一对,并分别评估每个个体,一次将它们分配给 cities
一个每次通过 for
循环并允许联合函数评估传递给它的对的每个实例的时间。
他们进一步解释说,使用 *
-operator 在理解中解压字典以产生所需的行为。
cities = cities.union(*(set(pair) for pair in flight_distances))
表达式:
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'}
这里我们将每个冻结集键转换为普通集并找到并集。
在第一个版本中,pair
在每个循环中都是一个 frozenset
,所以你可以用它做一个 union
,而在你的版本中,你尝试做一个联合set
个 frozenset
。
第一种情况归结为(在每次迭代时与 frozenset
合并):
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'}
...
在您的(最后一个)案例中,您正在执行以下操作(一个具有 frozenset
序列的联合):
cities = set()
cities.union([frozenset(['Atlanta', 'Chicago']), frozenset(['Atlanta', 'Dallas']), ...])
所以你有:
cities = {}
cities = {} U {{'Atlanta', 'Chicago'}, {'Atlanta', 'Dallas'}, ...}
= {{'Atlanta', 'Chicago'}, {'Atlanta', 'Dallas'}, ...} # Nothing disappears
因为没有两对是相同的,所以你会得到初始字典中所有对的集合,因为你传递的是 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}