DataQuest - 在Python中构建一个唯一的列表

时间:2015-03-29 15:35:37

标签: python

我目前正在使用DataQuest.io上的教程。 以下练习的目标是遍历数据集(flight_delays)并创建唯一载体列表。

#setting up empty lists
delays_by_carrier = {}
unique_carriers = []
#formula that returns column number based on column name
carrier_column = column_number_from_name("carrier")

for row in flight_delays:
    if row[carrier_column] in unique_carriers == False:
        unique_carriers.append(row[carrier_column])
print (unique_carriers)

print(unique_carriers)命令返回一个空列表,而我期待一个唯一的载波列表。有人可以解释/纠正吗?

仅供参考 - 我设法通过另一种方法解决了这个问题。我仍然有兴趣看看我如何解决这个问题!

2 个答案:

答案 0 :(得分:1)

代码中的问题是测试。您想检查运营商是否还在unique_carriers,但您的测试有点奇怪。在任何情况下,您都应该避免在测试中比较布尔值,因为测试已经是布尔值的比较。简单的表达式是:

if row[carrier_column] not in unique_carriers:
    ...

你想写的是:

if (row[carrier_column] in unique_carriers) == False:
    ...

那会有效(但不太优雅)。你也可以写not (row[carrier_column] in unique_carriers)

你的问题中有趣的是实际发生了什么。这不是关于运营商优先级的问题:您的代码不会被解释为row[carrier_column] in (unique_carriers == False),这会引发TypeError异常,表明您不能将in运算符与布尔值一起使用。

不,发生的事情是,在Python中,x < y < zin==(row[carrier_column] in unique_carriers) and (unique_carriers == False)都是这种意义上的比较。因此,您的陈述被解释为>>> def f(): ... if row[carrier_column] in unique_carriers == False: ... pass ...

您可以使用字节码进行确认。在这里,我做一个简单的函数来查看Python将用它做什么:

>>> dis.dis(f)
2         0 LOAD_GLOBAL              0 (row)
          3 LOAD_GLOBAL              1 (carrier_column)
          6 BINARY_SUBSCR
          7 LOAD_GLOBAL              2 (unique_carriers)
         10 DUP_TOP
         11 ROT_THREE
         12 COMPARE_OP               6 (in)
         15 JUMP_IF_FALSE_OR_POP    27
         18 LOAD_CONST               1 (False)
         21 COMPARE_OP               2 (==)
         24 JUMP_FORWARD             2 (to 29)
    >>   27 ROT_TWO
         28 POP_TOP
    >>   29 POP_JUMP_IF_FALSE       35

3        32 JUMP_FORWARD             0 (to 35)
    >>   35 LOAD_CONST               0 (None)
         38 RETURN_VALUE

然后,让我们看看字节码!

10

DUP_TOP,您会看到ROT_THREE复制堆栈顶部,当时是列表。然后unique_carriers row[carrier_column] unique_carriers 旋转堆栈,最终得到:

in

现在,您使用12True)进行第一次比较,如果18继续21unique_carriers来比较剩余的内容({{ 1}}因为其他2个已经与False一起弹出。就是这样,你的测试是:

if row[carrier_column] in unique_carriers:
    if unique_carriers == False:
        # do something

答案 1 :(得分:0)

感谢您的回答。要恢复,以下解决方案将起作用:

if row[carrier_column] not in unique_carriers:

if (row[carrier_column] in unique_carriers) == False:

关于为什么我的代码没有工作的解释有点让我头疼。但我现在明白了我创建的测试的复杂性,确保我首先尝试找到一个优雅的解决方案。

亲切的问候