2016-11-30 86 views
0

这里是我的榜样,如预期Python列表与循环会发生什么引用

import pandas as pd 

df_1 = pd.DataFrame({'A': [1,1]}) 
df_2 = pd.DataFrame({'A': [2,1]}) 

df_list = [df_1, df_2] 
df_list = [x.loc[x['A'] == 1] for x in df_list] 

print(df_list[0]) 
print('____') 
print(df_list[1]) 

下面这工作是输出:

A 
0 1 
1 1 
____ 
    A 
1 1 

下面是例子,这是我期待产生类似的输出,但它并不:

import pandas as pd 

df_1 = pd.DataFrame({'A': [1,1]}) 
df_2 = pd.DataFrame({'A': [2,1]}) 

df_list = [df_1, df_2] 

for el in df_list: 
    el = el.loc[el['A']==1] 

print(df_list[0]) 
print('____') 
print(df_list[1]) 

这里是输出

A 
0 1 
1 1 
____ 
    A 
0 2 
1 1 

第二个例子有什么问题。我正在参考一个对象来猜测发生的事情,我在哪里可以阅读更多关于它的内容?

回答

1

在第一种情况下,您正在通过列表理解重写df_list。第二个遍历数据框的列表,但从不改变数据框本身。他们的关键在于列表理解实际上返回一个新列表,并重写df_list。

下面是一个说明性的例子(请原谅所有打印语句的..):

lst = ['a', 'b'] 
print('Memory address of the list: %s' % hex(id(lst))) 
print('--'*10) 
print('BEGIN FOR LOOP') 
print('--'*10) 
for letter in lst: 
    letter = 'c' 
print(lst) 
print('Memory address of the list: %s' % hex(id(lst))) 
print('--'*10) 
print('Now use a list comprehension, which will return a new list') 
lst = ['c' for letter in lst] 
print(lst) 
print('Memory address of the list: %s' % hex(id(lst))) 
print(letter) # letter is still a variable that has been declared 

输出这样的:

Memory address of the list: 0x10b45b2c8 
-------------------- 
BEGIN FOR LOOP 
-------------------- 
['a', 'b'] 
Memory address of the list: 0x10b45b2c8 # Same list 
-------------------- 
Now use a list comprehension, which will return a new list 
['c', 'c'] 
Memory address of the list: 0x10b455b08 # New list, new memory spot 

注意,使用列表理解之后,内存地址实际上改变。这意味着你正在看一个全新的对象。 for循环之后,您正在查看相同的旧列表。在for循环中,您将变量el重新分配给每个迭代。

这会做你期待什么,因为要存储的新的价值,以一个新的列表:

import pandas as pd 

df_1 = pd.DataFrame({'A': [1,1]}) 
df_2 = pd.DataFrame({'A': [2,1]}) 

df_list = [df_1, df_2] 

lst = [] 
for el in df_list: 
    lst.append(el.loc[el['A']==1]) 

print(lst[0]) 
print('____') 
print(lst[1])