【问题标题】:Create dictionary from lists matching with conditional从与条件匹配的列表创建字典
【发布时间】:2021-12-11 08:18:24
【问题描述】:

鉴于这些示例列表

main = ['dayn is the one', 'styn is a main', 'tyrn is the third main']
lst2 = ['dayz', 'stzn', 'tyrm']
lst3 = ['stywerwe', 'tyrmadsf', 'dayttt']

我正在尝试创建一个字典,该字典将主列表的每个元素作为键,并且仅将那些与 main 中任何值的前三个字符以及 lst2 或 lst3 中的任何值匹配的元素作为值的列表那个键。

我尝试了几个版本都无济于事。

matched = {}

for x in main:
    for y in lst2:
        if x[:3] == y[:3]:
            matched[x] = y

这段代码让我很接近,但结果却不尽如人意:

{'dayn is the one': 'dayz', 'tyrn is the third main': 'tyrm'}

我的实际数据是我公司的四个不同命名位置的列表。初始列表是这些位置的正确名称,并且创建了来自三个不同来源的其他三个列表,以便这些作者使用这些名称的缩短版本等。所以,如果我可以匹配主列表和之间的前 5 个字符其他三个中的每一个,我都可以创建一个映射字典来纠正其他三个来源中这些设施的非常规命名的版本。预期的输出是这样的:

示例列表项:

main = ['dayn is the one', 'styn is a main', 'tyrn is the third main']
lst2 = ['dayz', 'stzn', 'tyrm']
lst3 = ['styzerwe', 'tyrmadsf', 'dayttt']
lst4 = ['dayl', 'styyzt', 'tyrl']

预期结果:

{'dayn is the one':['dayz','dayttt', 'dayl'],'styn is a main':['styzerwe', 'styyzt'],'tyrn is the third main':['tyrm', 'tyrmadsf', 'tyrl']} 

目标是使用上述字典,然后通过将其用作 pandas 中的映射对象来更正任何数据框中的设施名称的任何版本。在所有不同的命名约定中,前 5 个左右的字符是相同的,是确保匹配唯一名称的一种方式。

我研究了更新字典、有序字典、python 中的默认字典,但没有任何东西可以解决这个谜题。

【问题讨论】:

    标签: python dictionary mapping


    【解决方案1】:

    试试:

    main = ["dayn is the one", "styn is a main", "tyrn is the third main"]
    lst2 = ["dayz", "stzn", "tyrm"]
    lst3 = ["styzerwe", "tyrmadsf", "dayttt"]
    lst4 = ["dayl", "styyzt", "tyrl"]
    
    
    tmp = {}
    for l in [lst2, lst3, lst4]:
        for v in l:
            tmp.setdefault(v[:3], []).append(v)
    
    out = {v: tmp.get(v[:3], []) for v in main}
    print(out)
    

    打印:

    {
        "dayn is the one": ["dayz", "dayttt", "dayl"],
        "styn is a main": ["styzerwe", "styyzt"],
        "tyrn is the third main": ["tyrm", "tyrmadsf", "tyrl"],
    }
    

    【讨论】:

    • 这个答案有效。然而,它暴露了我的另一个弱点。在前五个字符左右之后,某些术语将唯一匹配,这是有效的。但是,我有一些我必须到第 9 个角色才能获得独特的价值。例如Greenbrier(带有“e”)和 Greenbriar(带有“a”)导致此结果 {'Greebrier": ["greenbrier", "greenbriar"] 因为当然,它们匹配前五个字符。但是,匹配到第九个字符全部失败,因为某些值只有五个字符。考虑...
    【解决方案2】:
    from itertools import chain
    
    main = ['dayn is the one', 'styn is a main', 'tyrn is the third main']
    lst2 = ['dayz', 'stzn', 'tyrm']
    lst3 = ['styzerwe', 'tyrmadsf', 'dayttt']
    lst4 = ['dayl', 'styyzt', 'tyrl']
    
    def create_dict(main, match=3, *rest):
        result = {item[:match]:[item, []] for item in main}
        result['unmatched'] = ['unmatched', []]
        for item in chain(*rest):
            (result.get(item[:match]) or result['unmatched'])[1].append(item)
        return dict(result.values())
    
    result = create_dict(main, 3, lst2, lst3, lst4)
    print(result)
    

    输出:

    {'dayn is the one': ['dayz', 'dayttt', 'dayl'], 
     'styn is a main': ['styzerwe', 'styyzt'], 
     'tyrn is the third main': ['tyrm', 'tyrmadsf', 'tyrl'], 
     'unmatched': ['stzn']}
    

    【讨论】:

      【解决方案3】:

      只有几行

      main = ['dayn is the one', 'styn is a main', 'tyrn is the third main']
      lst2 = ['dayz', 'stzn', 'tyrm']
      lst3 = ['styzerwe', 'tyrmadsf', 'dayttt']
      lst4 = ['dayl', 'styyzt', 'tyrl']
      
      keys= tuple(main)
      data= tuple(lst2+lst3+lst4)
      elem=  [[e for e in data if e.startswith(keys[i][:3])] for i in(range(3))]
      result= dict(zip(keys, elem))
      
      print(result)
      

      [输出]

      {'dayn is the one': ['dayz', 'dayttt', 'dayl'], 'styn is a main': ['styzerwe', 'styyzt'], 'tyrn is the third main': ['tyrm', 'tyrmadsf', 'tyrl']}
      

      【讨论】:

        猜你喜欢
        • 2014-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-06
        • 1970-01-01
        相关资源
        最近更新 更多