根据字典键将值附加到列表

时间:2019-12-04 21:10:45

标签: python-3.x pandas numpy

从去年夏天开始,我就开始为研究编写Python脚本,并且一直在学习这种语言。对于我当前的工作,我有一个列表字典, sample_range_dict ,该字典以 descriptor_cols 作为键进行初始化,并清空值列表。示例代码如下:

import numpy as np
import pandas as pd

def rangeFunc(arr):
    return (np.max(arr) - np.min(arr))

df_sample = pd.DataFrame(np.random.rand(2000, 4), columns=list("ABCD")) #random dataframe for testing
col_list = df_sample.columns

sample_range_dict = dict.fromkeys(col_list, []) #creates dictionary where each key pairs with an empty list
rand_df = df_sample.sample(n=20) #make a new dataframe with 20 random rows of df_sample

我想遍历rand_df中的每一列并计算值的范围,将每个范围放入具有指定列名的列表中(例如sample_range_dict [“ A”] = [A列中的范围])。以下是我最初认为用于此目的的代码:

for d in col_list:
    sample_range_dict[d].append(rangeFunc(rand_df[d].tolist()))

但是,打印sample_range_dict会显示每个键具有相同的4个值列表,而不是每个键都在列表中包含一项:

{'A': [0.8404352070810013,
  0.9766398946246098,
  0.9364714925930782,
  0.9801082480908744],
 'B': [0.8404352070810013,
  0.9766398946246098,
  0.9364714925930782,
  0.9801082480908744],
 'C': [0.8404352070810013,
  0.9766398946246098,
  0.9364714925930782,
  0.9801082480908744],
 'D': [0.8404352070810013,
  0.9766398946246098,
  0.9364714925930782,
  0.9801082480908744]}

我确定第一个值是“ A”的范围,第二个值是“ B”的范围,依此类推。我的问题是为什么会发生这种情况,以及如何重写代码以使列表中的每个键都有一个项目。

P.S。我正在寻找一个迭代过程,因此使用列表而不是单个数字。

1 个答案:

答案 0 :(得分:1)

问题是这一行:

sample_range_dict = dict.fromkeys(col_list, [])

您仅创建了一个列表。您没有四个具有相同元素的列表。您有一个列表,并有四个引用。通过一个引用添加到该元素时,该元素通过另一个引用可见,因为它是同一列表:

>>> a = dict.fromkeys(['x', 'y', 'z'], [])
>>> a['x'] is a['y']
True
>>> a['x'].append(5)
>>> a['y']
[5]

如果您希望每个键都有一个不同的列表,请为每个键创建一个新列表:

>>> a = { k: [] for k in ['x', 'y', 'z'] }
>>> a['x'] is a['y']
False
>>> a['x'].append(5)
>>> a['y']
[]

或使用defaultdict为您做到这一点:

>>> from collections import defaultdict
>>> a = defaultdict(list)
>>> a['x'] is a['y']
False
>>> a['x'].append(5)
>>> a['y']
[]