连续if语句:执行顺序

时间:2017-12-27 19:20:10

标签: python if-statement

这是我的Python代码:

my_constant = 5
my_constant_2 = 6
list_of_lists = [[3,2],[4,7]]

my_new_list = []

for i in list_of_lists:
    my_dict = {}
    for j in i:    
        if j > my_constant:
            my_dict["a"] = "Hello"
            my_dict["b"] = "Hello"
            print(my_dict)
            my_new_list.append(my_dict)
        if j > my_constant_2:
            my_dict["a"] = "Hello"
            my_dict["b"] = "Bye"
            print(my_dict)
            my_new_list.append(my_dict)


print(my_new_list)

结果如下:

{'a': 'Hello', 'b': 'Hello'}
{'a': 'Hello', 'b': 'Bye'}
[{'a': 'Hello', 'b': 'Bye'}, {'a': 'Hello', 'b': 'Bye'}]

结果的前两行是根据我的预期,但第三行不是。我希望如此:

[{'a': 'Hello', 'b': 'Hello'}, {'a': 'Hello', 'b': 'Bye'}]

所以看起来当循环在追加到my_new_list之前等待第二个“if”时,我们这样的my_new_list会获得两倍于新的my_dict。

我知道下面的代码解决了这个问题(即在“if”中移动my_dict):

my_constant = 5
my_constant_2 = 6
list_of_lists = [[3,2],[4,7]]

my_new_list = []

for i in list_of_lists:
    for j in i:        
        if j > my_constant:
            my_dict = {}
            my_dict["a"] = "Hello"
            my_dict["b"] = "Hello"
            print(my_dict)
            my_new_list.append(my_dict)
        if j > my_constant_2:
            my_dict = {}
            my_dict["a"] = "Hello"
            my_dict["b"] = "Bye"
            print(my_dict)
            my_new_list.append(my_dict)


print(my_new_list)

但是,实际上my_dict不是空的,并且使用了一个函数来创建它(并且需要一些时间)。此外,还有更多的“ifs”,所以我不想使用上面的代码。

有没有办法克服它?

感谢。

3 个答案:

答案 0 :(得分:1)

  

您一次又一次地重复使用同一个对象

使用deepcopy:

from copy import deepcopy
my_constant = 5

my_constant_2 = 6
list_of_lists = [[3,2],[4,7]]

my_new_list = []

for i in list_of_lists:
    my_dict = {}
    for j in i:
        if j > my_constant:
            my_dict["a"] = "Hello"
            my_dict["b"] = "Hello"
            print(my_dict)
            my_new_list.append(deepcopy(my_dict))
        if j > my_constant_2:
            my_dict["a"] = "Hello"
            my_dict["b"] = "Bye"
            print(my_dict)
            my_new_list.append(my_dict)


print(my_new_list)

输出:

{'b': 'Hello', 'a': 'Hello'}
{'b': 'Bye', 'a': 'Hello'}
[{'b': 'Hello', 'a': 'Hello'}, {'b': 'Bye', 'a': 'Hello'}]

为什么deepcopy()为什么不复制?

补充说明:

为了理解deepcopy vs copy,这里是示例代码:

  

让我们通过一个小例子来探讨你的问题:

所以假设你有一个清单:

a=['something']

还有第二个列表,其中包含:

list_1=[a,a,a]

所以当你这样做时:

a[0]="something_else"

您认为list_1的输出是什么?

我们来看看:

a=['something']
list_1=[a,a,a]


a[0]="something_else"
print(list_1)

输出:

[['something_else'], ['something_else'], ['something_else']]

因为在python变量中没有存储值,变量只是引用对象而对象存储值所以在list_1中所有变量都指向同一个对象:

检查:

for i in list_1:
    print(id(i))

输出:

4329477768
4329477768
4329477768
  

尝试深度扫描:

     

为什么deepcopy为什么不copy

假设你有这样的词:

dict_cell = {'item1': [20,34], 'item2': [25,9]}

您使用此dict_cell运行代码并获得输出:

[[{'item2': [25, 9], 'item1': 2}, {'item2': [25, 9], 'item1': [20, 34]}], [{'item2': [25, 9], 'item1': [20, 34]}, {'item2': [25, 9], 'item1': [20, 34]}]]

现在让我们尝试更改原始的dict值:

dict_cell = {'item1': [20,34], 'item2': [25,9]}
width = 2
height = 2
array = []
for i in range(height):
    row=[]
    for j in range(width):
        row.append(dict_cell.copy())
    array.append(row)
array[0][0]['item1'] =2


for key,value in dict_cell.items():
    value[0]='changed'

print(array,'\n')

输出:

[[{'item1': 2, 'item2': ['changed', 9]}, {'item1': ['changed', 34], 'item2': ['changed', 9]}], [{'item1': ['changed', 34], 'item2': ['changed', 9]}, {'item1': ['changed', 34], 'item2': ['changed', 9]}]] 

我们修改了orional dict但它改变了数组列表的dict中的内容,因为这是dict的浅层副本。它复制了dict但没有复制嵌套列表。

  

解决方案:

使用deepcopy。

答案 1 :(得分:1)

my_constant = 5
my_constant_2 = 6
list_of_lists = [[3,2],[4,7]]

my_new_list = []

for i in list_of_lists:
    my_dict = {}
    for j in i:    
        if j > my_constant:
            my_dict["a"] = "Hello"
            my_dict["b"] = "Hello"
            print(my_dict)
            my_new_list.append(my_dict.copy())
        if j > my_constant_2:
            my_dict["a"] = "Hello"
            my_dict["b"] = "Bye"
            print(my_dict)
            my_new_list.append(my_dict.copy())


print(my_new_list)

因为在你的代码中,my_new_list [0]和my_new_list [1]是同一个对象。 所以当你改变my_dict时如果j> my_constant_2块,然后也将更改my_new_list [0]。 将对象添加到my_new_list时,请使用copy或deepcopy。 copy()函数将执行浅拷贝。 因此,为了安全起见,使用深度镜是很好的。

我认为my_dict初始化位置不合适。 请考虑一下。

答案 2 :(得分:0)

代码的两个版本之间的区别在于第一个代码将相同的dict多次附加到列表中。在这种情况下,列表将始终包含相同的dict。

但是,没有什么可以阻止您使用预先计算的值填充my_dict

defaults = {'some': 'common', 'values': 'here'}

for i in list_of_lists:
    for j in i:        
        if j > my_constant:
            my_dict = defaults.copy()
            my_dict["a"] = "Hello"
            my_dict["b"] = "Hello"
            print(my_dict)
            my_new_list.append(my_dict)

defaults可以在循环内计算,如果它取决于ij

如果您担心数据重复,只需更改程序的逻辑,不要在my_new_list中存储重复值。