【问题标题】:How to create a dictionary of values that contain a tuple and list如何创建包含元组和列表的值字典
【发布时间】:2017-10-08 12:21:25
【问题描述】:

我正在尝试定义一个函数来创建这样的字典:

d = {}
d['aod'] = [('nt', 'P3', ['af1', 'af2', 'af3']),
            ('t', 'P3', ['af1', 'af2', 'af3']),
            ('nv', 'P3', ['af1', 'af2', 'af3'])]    

我可以得到这样的字典:

d = {'aod': ('nt', 'P3')}

使用下面的代码:

experiment = ['aod']
cond_peaks = ['nt_P3', 't_P3', 'nv_P3']
channel_lst = ['af1', 'af2', 'af3']

def create_dict(experiment, cond_peaks, channel_lst):
    d = {}
    for e in experiment:
        for cp in cond_peaks: 
            cond = cp.split('_')[0]
            peak = cp.split('_')[1]
            cond_peak_tup = cond, peak
            d[e] = cond_peak_tup
    return d

由于元组是不可变的,我无法将 channel_lst 添加到字典值中。我的问题是如何创建一个字典,其中的值包含一个元组和一个列表?

【问题讨论】:

    标签: python-3.x dictionary tuples


    【解决方案1】:

    您可以在dict comprehension 的一行中使用此输入进行此操作,如下例所示:

    experiment = ['aod']
    cond_peaks = ['nt_P3', 't_P3', 'nv_P3']
    channel_lst = ['af1', 'af2', 'af3']
    
    final = {k:[(j.split("_")[0],j.split("_")[1],channel_lst,) for j in cond_peaks] for k in experiment}
    
    
    print(final)
    

    输出:

    {'aod': [('nt', 'P3', ['af1', 'af2', 'af3']), ('t', 'P3', ['af1', 'af2', 'af3']), ('nv', 'P3', ['af1', 'af2', 'af3'])]}
    

    【讨论】:

    • tuple(j.split("_") + channel_lst) 不会产生所需的输出,因为它连接了两个列表。你必须做tuple(j.split("_") + [channel_lst]),如我回答的最后一部分所示。
    • 是的,你是对的。我没有检查它。感谢您的评论。
    【解决方案2】:

    你可以像这样定义你的元组:

    cond_peak_tup = cond, peak, channel_lst
    

    并使用临时列表,

    d = {}
    for e in experiment:
        l = []
        for cp in cond_peaks: 
            cond = cp.split('_')[0]
            peak = cp.split('_')[1]
            cond_peak_tup = cond, peak, channel_lst
            l.append(cond_peak_tup)
        d[e] = l
    return d
    

    更优雅的是,您还可以使用字典和列表推导式一次性创建所有内容(假设(*cp.split('_'), channel_lst) 语法为 Python 3.5 或更新版本):

    d = {e: [(*cp.split('_'), channel_lst) for cp in cond_peaks]
         for e in experiment}
    

    对于旧版本,您必须执行以下操作:

    d = {e: [tuple(cp.split('_') + [channel_lst]) for cp in cond_peaks]
         for e in experiment}
    

    在我看来,后一种解决方案不仅速度更快,而且对于 Python 识字者来说也更具可读性,而前者对于学习或调试目的很有用。但这当然是风格问题。

    【讨论】:

    • @Evey - *(*cp.split('_')中的作用是什么?
    • @e9e9s 如果xs = [x1, x2, x3],则表达式(*xs, y) 中的星号(*) 扩展列表(或任何可迭代的,实际上)使得(*xs, y) == (x1, x2, x3, y)。由于cp.split('_') 返回一个列表,这些以上述方式插入到元组中。有关其他示例,请参阅 PEP 448 (python.org/dev/peps/pep-0448)。这个符号实际上已经存在很长时间了,f(y, *xs) == f(y, x1, x2, x3) 和类似的语法在定义带有任意数量参数的函数时起作用。 :-)
    猜你喜欢
    • 2019-03-17
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2018-08-04
    • 2019-01-19
    • 2016-10-08
    • 2022-01-21
    • 2014-04-09
    相关资源
    最近更新 更多