繁体   English   中英

需要帮助来了解for循环的行为

[英]Need help understanding the behavior of a for loop

我正在阅读有关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循环会按预期拆包这些对,以便它生成一个包含每个城市实例的集合,同时尝试编写循环以理解理解时会拉出frozenset([city1, city2])配对并放置在集合中。

我不明白为什么pair会在第一个实例中给出城市字符串,而在第二个实例中传递Frozenset。

有人可以解释不同的行为吗?

注:由于解释霍尔特donkopotamus ,为什么这是表现不同的问题是,用理解评估的整个词典完全使得单分配给前cities变量,从而开创了一套frozensets的,其中作为标准for循环一次解开一对货币对并分别评估每个个体,通过for循环的每次传递将它们一次分配给cities ,并允许union函数评估传递给它的对的每个实例。

他们进一步解释说,使用*运算符将字典中的内容解压缩以产生所需的行为。

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 frozensetset

第一种情况归结为(每次迭代都具有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

由于有两对是相同的,你会得到一个集中的所有对你的初始字典,因为你传递一个setset (对)的城市,而不是一个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}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM