函数在第二次调用后返回不同的字典

Function returning different dictionary after second call

背景:

我正在尝试确定技术图纸尺寸与实际测量尺寸之间的差异。这些维度存储在两个字典中:actual_datadrawing_data。由于可以通过多种方式进行实际测量,因此将它们存储为列表以适应以下情况:

  1. 1x1 列表。这表示没有指定变化或公差的单一尺寸。
  2. 1x2 列表。这表示具有上限和下限或公差的尺寸。
  3. Nx1 个列表。这表示从大型组件的一个表面获取的奇异尺寸列表。
  4. Nx2 列表。这表示每个维度都有上限和下限或公差的列表。

为避免条件过多,我将所有矩阵分解为列表并为每个新列表(1x1 或 1x2)分配一个新键。

我的脚本:

import numpy as np

drawing_data = {
        'A': [394.60],
        'B': [629.85, 629.92],
        'C': [759.95, 760.00],
        'D': [839.95, 840.00],
        'E': [1779.50, 1780.50]
        }

actual_data = {
        'A': [390.00],
        'B': [629.88, 629.90],
        'C': [760.17, 760.25],
        'D': [[840.12, 840.18], [840.04, 840.06], [840.07, 840.07]],
        'E': [1780.00, 1780.00]
        }

如您所见,尺寸 D 的预期测量值介于 839.95 毫米和 840.00 毫米之间。但是,由于组件的大小,它在三个地方进行测量(因此,列表列表)。

def dimensional_deviation(drawing, actual):
    
    # If the actual data is of the type Nx1 or Nx2, it is split and converted into new dimensions of the
    # type 1x1 or 1x2 - new dictionary keys are created to accommodate the new dimensions, and the 
    # original dictionary entries are deleted.
    #---------------------------------------------------------------------------------------------------
    new_dict_drawing, new_dict_actual, keys_to_remove = {}, {}, []

    for dimension in drawing:
        
        if type(actual.get(dimension)[0]) is list:

            keys_to_remove.append(dimension) # Create a list of unnecessery dimensions
            
            for i, sublist in enumerate(actual.get(dimension)):
                
                new_dict_drawing[f'{dimension}{i + 1}'] = drawing.get(dimension) # Create new dimension
                new_dict_actual[f'{dimension}{i + 1}'] = sublist # Create new dimension
                                
    for dimension in keys_to_remove: # Remove all unnecessary dimensions from the original dicts
        
        drawing.pop(dimension, None)
        actual.pop(dimension, None)

    # Merge dictionaries:    
    drawing = {**drawing, **new_dict_drawing}
    actual = {**actual, **new_dict_actual}
    #---------------------------------------------------------------------------------------------------
    
    # Determine the deviation between the drawing and actual dimensions. The average of the upper and 
    # lower bounds is used to simplify each case.
    #---------------------------------------------------------------------------------------------------
    inspection_results = {}
    
    for dimension in drawing:
        
        drawing_value, actual_value = drawing.get(dimension), actual.get(dimension)
        
        drawing_ave, actual_ave = np.mean(drawing_value), np.mean(actual_value)

        deviation = drawing_ave - actual_ave
            
    # Create new dictionary of the repair requirements:
    #---------------------------------------------------------------------------------------------------
        inspection_results[f'{dimension}'] = round(deviation, 3)
    
    return inspection_results

我的问题:

当我第一次调用上面的代码时,我得到了想要的输出。尺寸 D 按预期分解并计算偏差。但是,当我第二次调用同一个函数时,关于维度 D 的所有内容都被完全忽略了,就好像密钥不存在一样:

print('First function call:')
print(dimensional_deviation(drawing=drawing_data, actual=actual_data))
print('---------------------------------------------------------------------------------------')

print('Second function call:')
print(dimensional_deviation(drawing=drawing_data, actual=actual_data))
print('---------------------------------------------------------------------------------------')

导致:

First function call:
{'A': 4.6, 'B': -0.005, 'C': -0.235, 'E': 0.0, 'D1': -0.175, 'D2': -0.075, 'D3': -0.095}
--------------------------------------------------------------------------------------- 
Second function call:
{'A': 4.6, 'B': -0.005, 'C': -0.235, 'E': 0.0}
--------------------------------------------------------------------------------------- 

我想我在某处覆盖了我的 drawing_dataactual_data,但我找不到问题所在。此外,这是我第一次使用字典,我怀疑我的密钥创建和删除可能不是最佳做法。

在我的评论中,您将看到 Create a list of unnecessary dimensions - 维度 D 就是一个例子,因为它在 D1、D2 和 D3 中被新考虑。

有人可以向我解释为什么我在第一次调用之后的每个后续函数调用中都会得到这个结果吗?

问题是原始词典被修改了(见上面的评论):

import numpy as np

drawing_data = {
        'A': [394.60],
        'B': [629.85, 629.92],
        'C': [759.95, 760.00],
        'D': [839.95, 840.00],
        'E': [1779.50, 1780.50]
        }

actual_data = {
        'A': [390.00],
        'B': [629.88, 629.90],
        'C': [760.17, 760.25],
        'D': [[840.12, 840.18], [840.04, 840.06], [840.07, 840.07]],
        'E': [1780.00, 1780.00]
        }
#-------------------------------------------------------------------------------------------------------

# The 'dimensional deviation' function takes the drawing data and actual data as arguments, returning a
# dictionary of dimensions and whether they require rectification or not (based one the drawing data).
#-------------------------------------------------------------------------------------------------------
def dimensional_deviation(drawing, actual):

    temp_dict_drawing = {}
    for key in drawing:
        temp_dict_drawing[key] = drawing.get(key)

    temp_dict_actual = {}
    for key in drawing:
        temp_dict_actual[key] = actual.get(key)
    
    # If the actual data is of the type Nx1 or Nx2, it is split and converted into new dimensions of the
    # type 1x1 or 1x2 - new dictionary keys are created to accommodate the new dimensions, and the 
    # original dictionary entries are deleted.
    #---------------------------------------------------------------------------------------------------
    new_dict_drawing, new_dict_actual, keys_to_remove = {}, {}, []

    for dimension in temp_dict_drawing:
        
        if type(temp_dict_actual.get(dimension)[0]) is list:

            keys_to_remove.append(dimension) # Create a list of unnecessery dimensions
            
            for i, sublist in enumerate(temp_dict_actual.get(dimension)):
                
                new_dict_drawing[f'{dimension}{i + 1}'] = temp_dict_drawing.get(dimension) # Create new dimension
                new_dict_actual[f'{dimension}{i + 1}'] = sublist # Create new dimension
                                
    for dimension in keys_to_remove: # Remove all unnecessary dimensions from the original dicts
        
        temp_dict_drawing.pop(dimension)
        temp_dict_actual.pop(dimension)

    # Merge dictionaries:    
    drawing_new = {**temp_dict_drawing, **new_dict_drawing}
    actual_new = {**temp_dict_actual, **new_dict_actual}
    #---------------------------------------------------------------------------------------------------
    
    # Determine the deviation between the drawing and actual dimensions. The average of the upper and 
    # lower bounds is used to simplify each case.
    #---------------------------------------------------------------------------------------------------
    inspection_results = {}
    
    for dimension in drawing_new:
        
        drawing_value, actual_value = drawing_new.get(dimension), actual_new.get(dimension) # Fetch the data

        drawing_ave, actual_ave = np.mean(drawing_value), np.mean(actual_value) # Calculate averages

        deviation = drawing_ave - actual_ave
            
    # Create new dictionary of the repair requirements:
    #---------------------------------------------------------------------------------------------------
        inspection_results[f'{dimension}'] = round(deviation, 3)
    
    return inspection_results

另外,copy.deepcopy() 也产生了正确的结果:

Deep copy of a dict in python