在 Python 中将带有默认参数的元组传递给函数?

Passing tuples with default arguments to a function in Python?

提问人:YoYoYo 提问时间:9/12/2022 更新时间:9/12/2022 访问量:65

问:

我必须通过从一大堆元组中传递预定义的参数来调用函数。

所有函数参数都是默认类型,它们会根据 CATEGORY 参数更改其长度和类型(请参阅下面的示例代码以更好地理解我想说的内容)。

LIST_ALL_BETA = [1, 2, 3, 4, 5, 7, 23, 28, 29] # huge list with numbers, all integers
LIST_ALL_FREQ = [1.23, 1.30, 1.35, 2.18, 2.57] # huge list of floats
def MyFunction(idx=None, CATEGORY=None, LOW_LIMIT=None, HIGH_LIMIT=None, ALL_BETA=None, ALL_FREQ=None, NONE=None, LAST_X=None, LST=None):
    if CATEGORY=="COUNTED":
        partial_COUNTED_lst = globals()[f'LIST_COUNTED_LAST_{LAST_X}']
        return [x for x in range(1, 81) if partial_COUNTED_lst[idx][x-1] is not None if LOW_LIMIT <= partial_COUNTED_lst[idx][x-1] <= HIGH_LIMIT]
    elif CATEGORY=="BETA":
        if ALL_BETA==True:
            if NONE == "ignored":
                all_BETA_lst = LIST_ALL_BETA
                return [x for x in range(1, 81) if all_BETA_lst[idx][x-1] is not None if LOW_LIMIT <= all_BETA_lst[idx][x-1] <= HIGH_LIMIT]
            else: # NONE = 0
                all_BETA_lst = LIST_ALL_BETA
                return [x for x in range(1, 81) if LOW_LIMIT <= [y if y is not None else 0 for y in all_BETA_lst[idx]][x-1] <= HIGH_LIMIT]
        else:
            if NONE == "ignored":
                all_BETA_lst = globals()[f'LIST_BETA_LAST_{LAST_X}']
                return [x for x in range(1, 81) if all_BETA_lst[idx][x-1] is not None if LOW_LIMIT <= all_BETA_lst[idx][x-1] <= HIGH_LIMIT]
            else: # NONE = 0
                all_BETA_lst = globals()[f'LIST_BETA_LAST_{LAST_X}']
                return [x for x in range(1, 81) if LOW_LIMIT <= [y if y is not None else 0 for y in all_BETA_lst[idx]][x-1] <= HIGH_LIMIT]
    elif CATEGORY=="FREQUENCY":
        if ALL_FREQ==True:
            all_frequency_lst = LIST_ALL_FREQ
            return  [x for x in range(1, 81) if all_frequency_lst[idx][x-1] is not None if LOW_LIMIT <= all_frequency_lst[idx][x-1] <= HIGH_LIMIT]
        else:
            all_frequency_lst = globals()[f'LIST_FREQ_LAST_{LAST_X}']
            return  [x for x in range(1, 81) if all_frequency_lst[idx][x-1] is not None if LOW_LIMIT <= all_frequency_lst[idx][x-1] <= HIGH_LIMIT]
    elif CATEGORY=="CMB4":
        return LST[idx]

# huge list of parameters:
parametters = [
    (idx=23, CATEGORY="COUNTED", LOW_LIMIT=265, HIGH_LIMIT=269, LAST_X=1000),
    (idx=23, CATEGORY="COUNTED", LOW_LIMIT=241, HIGH_LIMIT=272, LAST_X=1000),
    (idx=23, CATEGORY="COUNTED", LOW_LIMIT=16, HIGH_LIMIT=19, LAST_X=100),
    (idx=23, CATEGORY="BETA", LOW_LIMIT=1.55, HIGH_LIMIT=2.01, ALL_BETA=True, NONE="ignored", LAST_X=0),
    (idx=23, CATEGORY="BETA", LOW_LIMIT=1.55, HIGH_LIMIT=2.01, ALL_BETA=True, NONE="0", LAST_X=0),
    (idx=23, CATEGORY="BETA", LOW_LIMIT=0.0, HIGH_LIMIT=5.3, ALL_BETA=True, NONE="ignored", LAST_X=0),
    (idx=23, CATEGORY="FREQUENCY", LOW_LIMIT=0.2587, HIGH_LIMIT=0.2608, ALL_FREQ=True, LAST_X=0),
    (idx=23, CATEGORY="FREQUENCY", LOW_LIMIT=0.2478, HIGH_LIMIT=0.2607, ALL_FREQ=True, LAST_X=0),
    (idx=23, CATEGORY="FREQUENCY", LOW_LIMIT=0.259, HIGH_LIMIT=0.261, ALL_FREQ=True, LAST_X=0),
    (idx=23, CATEGORY="CMB4", LST = LIST_CMB4_LAST_1000_1),
    (idx=23, CATEGORY="CMB4", LST = LIST_CMB4_LAST_1000_2)
]

问题是我无法创建这种元组,因为它会给我带来“无效的语法错误”。

请问有什么想法吗?

先谢谢你!

PS 我也发现了这个话题,它以某种方式解决了同样的问题,但它对我没有帮助,因为问题是不同的,而且我并不真正了解所涉及的情况,所以我可以使用解决方案来解决我正在问的这个问题。

python-3.x 参数 传递

评论

1赞 wholevinski 9/12/2022
你能包括你得到的无效语法错误吗?编辑:啊,我明白了,元组的语法。为此,您可能希望使用类似 dict unpacking 的东西。我会发布一个答案。
1赞 C. Cooney 9/12/2022
我相信您正在寻找一个字典列表,或者一个列表字典。例如,parameter_01 = {'idx': 23, 'CATEGORY': 'COUNTED', ...},然后创建一个列表。或者,将所有 idx 项目放入列表,将所有类别项目放入列表(保持顺序对齐),然后撰写列表字典。
0赞 YoYoYo 9/12/2022
如果有人发布解决方案,也请发布如何以这种方式调用该函数,因为我不认为这也可能是一个问题。先谢谢你!

答:

1赞 wholevinski 9/12/2022 #1

与其尝试使用元组进行调用,不如使用字典列表并使用称为字典解包的东西。如果在字典之前添加并将其传递到函数调用中,它会将键值对解压缩到函数的命名参数中。**

新参数列表如下所示:

parameters = [
    {"idx": 23, "CATEGORY": "COUNTED", "LOW_LIMIT": 265, "HIGH_LIMIT": 269, "LAST_X": 1000},
    {"idx": 23, "CATEGORY": "COUNTED", "LOW_LIMIT": 241, "HIGH_LIMIT": 272, "LAST_X": 1000},
    {"idx": 23, "CATEGORY": "COUNTED", "LOW_LIMIT": 16, "HIGH_LIMIT": 19, "LAST_X": 100},
    {"idx": 23, "CATEGORY": "BETA", "LOW_LIMIT": 1.55, "HIGH_LIMIT": 2.01, "ALL_BETA": True, "NONE": "ignored", "LAST_X": 0},
    {"idx": 23, "CATEGORY": "BETA", "LOW_LIMIT": 1.55, "HIGH_LIMIT": 2.01, "ALL_BETA": True, "NONE": "0", "LAST_X": 0},
    {"idx": 23, "CATEGORY": "BETA", "LOW_LIMIT": 0.0, "HIGH_LIMIT": 5.3, "ALL_BETA": True, "NONE": "ignored", "LAST_X": 0},
    {"idx": 23, "CATEGORY": "FREQUENCY", "LOW_LIMIT": 0.2587, "HIGH_LIMIT": 0.2608, "ALL_FREQ": True, "LAST_X": 0},
    {"idx": 23, "CATEGORY": "FREQUENCY", "LOW_LIMIT": 0.2478, "HIGH_LIMIT": 0.2607, "ALL_FREQ": True, "LAST_X": 0},
    {"idx": 23, "CATEGORY": "FREQUENCY", "LOW_LIMIT": 0.259, "HIGH_LIMIT": 0.261, "ALL_FREQ": True, "LAST_X": 0},
    {"idx": 23, "CATEGORY": "CMB4", "LST": LIST_CMB4_LAST_1000_1},
    {"idx": 23, "CATEGORY": "CMB4", "LST": LIST_CMB4_LAST_1000_2}
]

以下是调用函数的方式:

for parameter_dict in parameters:
    MyFunction(**parameter_dict)

1 个附加反馈项:您应该为每个类别 IMO 创建一个单独的功能。试图将所有这些塞进一个函数中将很难维护和混淆。也许创建一个 、 、 和 函数。然后,您可以在某处使用一些控制逻辑,根据每个类别调用单独的函数。process_countedprocess_betaprocess_frequencyprocess_cmb4