将列表值枚举到字典列表中

时间:2014-07-16 00:40:56

标签: list python-2.7 dictionary

我有一个字典列表,我正在尝试根据列表中其他其他变量的值分配字典键:值对。我想将每个变量列表的“ith”值分配给block_params_list中的第i个字典,并将变量名称(作为字符串)作为键。问题是虽然代码适当地分配了值(如“pprint(item)”所示),但是当整个枚举循环结束时,“block_params_list”中的每个项目都等于最后一个项目的值。

我无法解释这种行为。有人可以帮忙吗?谢谢!

'''empty list of dictionaries'''
block_params_list = [{}] * 5

'''variable lists to go into the dictionaries'''
ran_iti = [False]*2 + [True]*3
iti_len = [1,2,4,8,16]
trial_cnt = [5,10,15,20,25]

'''the loops'''
param_list= ['iti_len','trial_cnt','ran_iti']#key values, also variable names
for i,item in enumerate(block_params_list):
    for param in param_list:
        item[param] = eval(param)[i]
    pprint(item) #check what each item value is after assignment

pprint(block_params_list) #prints a list of dictionaries that are
                          #only equal to the very last item assigned

1 个答案:

答案 0 :(得分:3)

你已经遇到了一个普通的问题'在Python中,在你的第一行代码上:

# Create a list of five empty dictionaries
>>> block_params_list = [{}] * 5

指令[{}] * 5相当于这样做:

>>> d = {}
>>> [d, d, d, d, d]

该列表包含对同一字典的五个引用。你说" block_params_list'中的每个项目。等于最后一项" - 这是一种幻觉,实际上只有一个项目在" block_params_list"并且你正在分配它,然后查看它,五次通过五个不同的引用。

您需要使用循环来创建列表,以确保创建五个不同的词典:

block_params_list = []
for i in range(5):
    block_params_list.append({})

block_params_list = [{} for i in range(5)]

NB。您可以安全地[1] * 5获取数字列表,或[True] * 5获取真实列表,或['A'] * 5获取字符列表'。区别在于您是否最终更改列表,或者您是否更改了列表引用的事物。顶级或二级。

e.g. making a list of numbers, assinging to it does this:

before:
nums = [1] * 3
list_start
    entry 0 --> 1
    entry 1 --> 1
    entry 2 --> 1
list_end

nums[0] = 8

after:
list_start
    entry 0 -xx 1
            \-> 8
    entry 1 --> 1
    entry 2 --> 1
list_end

虽然按照您的方式制作字典列表并分配给它,但是这样做:

before:
blocks = [{}] * 3
list_start
    entry 0 --> {}
    entry 1 --/
    entry 2 -/ 
list_end

first_block = blocks[0]
first_block['test'] = 8

after:
list_start
    entry 0 --> {'test':8}
    entry 1 --/
    entry 2 -/ 
list_end

在第一个示例中,列表中的一个引用必须更改。您无法从列表中提取数字并更改数字,您只能在列表中添加不同的数字。

在第二个示例中,列表本身根本没有变化,您将分配给列表引用的字典。因此,虽然您感觉要更新列表中的每个元素,但实际上并非如此,因为列表中没有字典,并且引用了字典在其中。