Python 如何根据子列表的某些规则和条件更改子列表列表中的项目?

Python 如何根据子列表的某些规则和条件更改子列表列表中的项目?,python,list,sublist,Python,List,Sublist,我有一个由三项组成的子列表。子列表中只有第一项和最后一项重要,因为我想根据列表中最后一项的频率更改所有子列表中的最后一项 Desired_List = lst = [['A','abc','id1'],['A','def','id1'],['A','ghi','id1'],['A','ijk','id1'],['A','lmn','id1'],['B','abc','id3'],['B','def','id3'],['B','ghi','id3'],['B','ijk','id3'],['B',

我有一个由三项组成的子列表。子列表中只有第一项和最后一项重要,因为我想根据列表中最后一项的频率更改所有子列表中的最后一项

Desired_List = lst = [['A','abc','id1'],['A','def','id1'],['A','ghi','id1'],['A','ijk','id1'],['A','lmn','id1'],['B','abc','id3'],['B','def','id3'],['B','ghi','id3'],['B','ijk','id3'],['B','lmn','id3'],['C','xyz','id6'],['C','lmn','id6'],['C','aaa','id6']]
这是我的清单:

lst = [['A','abc','id1'],['A','def','id2'],['A','ghi','id1'],['A','ijk','id1'],['A','lmn','id2'],['B','abc','id3'],['B','def','id3'],['B','ghi','id3'],['B','ijk','id3'],['B','lmn','id'],['C','xyz','id6'],['C','lmn','id6'],['C','aaa','id5']]
例如,A以id1而不是id2出现最多,因此我想用id1替换所有出现的id2。对于B,id3是最常见的,因此我想用id3替换任何其他实例,这意味着我只想用“id3”替换B的“id”。对于C,我想用“id6”替换“id5”的实例,因为“id6”在列表中出现得最多

Desired_List = lst = [['A','abc','id1'],['A','def','id1'],['A','ghi','id1'],['A','ijk','id1'],['A','lmn','id1'],['B','abc','id3'],['B','def','id3'],['B','ghi','id3'],['B','ijk','id3'],['B','lmn','id3'],['C','xyz','id6'],['C','lmn','id6'],['C','aaa','id6']]

我还应该提到,这将在一个非常大的列表上完成,因此需要速度和效率。

直接数据处理使用上面的特殊要求,我可以提出以下算法

第一次扫描:收集每个按键的频率信息(即A、B、C):

然后,查看与每个键关联的“值”(即
{'A':'id1'}
):

最后,遍历原始列表并使用上表替换值:

>>> newlst = [[key, unused, maxtable[key]] for key, unused, val in lst]
>>> print newlst
[['A', 'abc', 'id1'], ['A', 'def', 'id1'], ['A', 'ghi', 'id1'], ['A', 'ijk', 'id1'], ['A', 'lmn', 'id1'], ['B', 'abc', 'id3'], ['B', 'def', 'id3'], ['B', 'ghi', 'id3'], ['B', 'ijk', 'id3'], ['B', 'lmn', 'id3'], ['C', 'xyz', 'id6'], ['C', 'lmn', 'id6'], ['C', 'aaa', 'id6']]

这与Santa提供的解决方案几乎相同,但我将几个步骤合并为一个步骤,因为我们可以在收集频率时扫描最大值:

def fix_by_frequency(triple_list):
    freq = {}

    for key, _, value in triple_list:
        # Get existing data
        data = freq[key] = \
            freq.get(key, {'max_value': value, 'max_count': 1, 'counts': {}})

        # Increment the count
        count = data['counts'][value] = data['counts'].get(value, 0) + 1

        # Update the most frequently seen
        if count > data['max_count']:
            data['max_value'], data['max_count'] = value, count

    # Use the maximums to map the list
    return [[key, mid, freq[key]['max_value']] for key, mid, _ in triple_list]

这已经为可读性(我认为,做得好!)而不是原始速度进行了一些优化。例如,您可能不想在不需要时回写dict,或者维护一个单独的max dict,以防止在列表末尾的理解中查找两个键。

此外,您打算在之后如何处理所需的列表?这可能会影响它应该采取的形式(最有可能的情况是,为了达到您提到的效率,您需要存储一些比平面值更奇特的东西)。
def fix_by_frequency(triple_list):
    freq = {}

    for key, _, value in triple_list:
        # Get existing data
        data = freq[key] = \
            freq.get(key, {'max_value': value, 'max_count': 1, 'counts': {}})

        # Increment the count
        count = data['counts'][value] = data['counts'].get(value, 0) + 1

        # Update the most frequently seen
        if count > data['max_count']:
            data['max_value'], data['max_count'] = value, count

    # Use the maximums to map the list
    return [[key, mid, freq[key]['max_value']] for key, mid, _ in triple_list]