【问题标题】:Python dictionaries: merging multiple value lists into a single list of unique valuesPython字典:将多个值列表合并为一个唯一值列表
【发布时间】:2013-07-30 18:11:11
【问题描述】:

我只是在使用 Python 2.7 学习 Python。我有一个包含两列的 csv 文件。列是:

Col_id:条目可以是单个收集器,也可以是组

Participant_Col_id:如果 Coll_id 是单个收集器,则该值将为空。如果 Coll_id 是一个组,那么组中的每个 Participant 都会有一行。

这里有一个示例:

Coll_id,Participant_Coll_id<br>
ARA,ARG  
ARA,RAT  
ARG,NULL  
BRSAR,SGMB  
BRSAR,SANTM  
BRSAR,CRSR  
BRSAR,RAT  
CRSR,NULL  
DBY,NULL  
HZIE,NULL  
RAT,NULL  
SANTM,NULL  
SGMB,NULL  
ARG,NULL  
DRS,CRSR  
DRS,RAT  
DRS,ARG  

对于每个收集器 (coll_id),我正在尝试创建他们收集的所有其他收集器的列表。我试图将代码放在一起来执行以下操作,现在已经很接近了:

#This is giving me a dictionary with each COLL_ID having a list of PARTICIPANT_COLL_IDs

with open('colls_mv1.csv', 'r') as f:
    reader = csv.DictReader(f, ['COLL_ID', 'PARTICIPANT_COLL_ID'])
    data1 = defaultdict(list)

    for line in reader:
        data1[line['COLL_ID']].append(line['PARTICIPANT_COLL_ID'])


#And this is giving me a dictionary with each PARTICIPANT_COLL_ID having a list of COLL_IDs
with open('colls_mv1.csv', 'r') as f:
    reader = csv.DictReader(f, ['COLL_ID', 'PARTICIPANT_COLL_ID'])
    data2 = defaultdict(list)

    for line in reader:
        if line['PARTICIPANT_COLL_ID'] != 'NULL':
            data2[line['PARTICIPANT_COLL_ID']].append(line['COLL_ID'])

dict3 = {k: [data1[i] for i in v] for k, v in data2.items()}

print dict3

我得到以下输出:

{'SGMB': [['SGMB', 'SANTM', 'CRSR', 'RAT']], 'CRSR': [['SGMB', 'SANTM', 'CRSR', 'RAT'], ['CRSR', 'RAT', 'ARG']], 'RAT': [['ARG', 'RAT'], ['SGMB', 'SANTM', 'CRSR', 'RAT'], ['CRSR', 'RAT', 'ARG']], 'PARTICIPANT_COLL_ID': [['PARTICIPANT_COLL_ID']], 'ARG': [['ARG', 'RAT'], ['CRSR', 'RAT', 'ARG']], 'SANTM': [['SGMB', 'SANTM', 'CRSR', 'RAT']]}

我想要的是将每个键的值列表合并在一起,删除重复项并从值列表中删除键:

{'SGMB': ['SANTM', 'CRSR', 'RAT'], 'CRSR': ['SGMB', 'SANTM', 'RAT', 'ARG'], 'RAT': ['ARG', 'SGMB', 'SANTM', 'CRSR'], 'PARTICIPANT_COLL_ID': [['PARTICIPANT_COLL_ID']], 'ARG': ['RAT', 'CRSR'], 'SANTM': ['SGMB', 'CRSR', 'RAT']}

【问题讨论】:

    标签: python python-2.7 dictionary


    【解决方案1】:

    遍历列表,删除键,去重

    >>> res = {'SGMB': [['SGMB', 'SANTM', 'CRSR', 'RAT']], 'CRSR': [['SGMB', 'SANTM', 'CRSR', 'RAT'], ['CRSR', 'RAT', 'ARG']], 'RAT': [['ARG', 'RAT'], ['SGMB', 'SANTM', 'CRSR', 'RAT'], ['CRSR', 'RAT', 'ARG']], 'PARTICIPANT_COLL_ID': [['PARTICIPANT_COLL_ID']], 'ARG': [['ARG', 'RAT'], ['CRSR', 'RAT', 'ARG']], 'SANTM': [['SGMB', 'SANTM', 'CRSR', 'RAT']]}
    >>> newres = {k: list({x for t in v for x in t if x != k}) for k, v in res.iteritems()}
    >>> newres
    {'SGMB': ['CRSR', 'SANTM', 'RAT'], 'CRSR': ['SANTM', 'SGMB', 'RAT', 'ARG'], 'RAT': ['CRSR', 'SANTM', 'SGMB', 'ARG'], 'PARTICIPANT_COLL_ID': [], 'ARG': ['CRSR', 'RAT'], 'SANTM': ['CRSR', 'RAT', 'SGMB']}
    

    演示:http://ideone.com/87HKM9

    【讨论】:

    • 这太接近了 - 非常感谢!!我只需要找到一种方法从每个列表中删除重复项 - 并准确计算出我刚刚使用的代码的含义:)
    • 可以使用集合和列表转换删除重复项,请参阅我的编辑。
    • 太棒了!非常感谢你的帮助。它完全符合我的要求。
    • 使用集合/字典理解:{k: list({x for t in v for x in t if x != k}) for k, v in res.iteritems()}
    • @falsetru 公平的建议,这将使它免于一次类型转换,因此更有效。谢谢。
    猜你喜欢
    • 2022-11-14
    • 2013-03-26
    • 2017-01-05
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多