【问题标题】:How to change the items in a list of sublists based on certain rules and conditions of those sublists?如何根据子列表的某些规则和条件更改子列表中的项目?
【发布时间】:2014-06-14 13:06:23
【问题描述】:

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

这是我的清单:

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 替换所有以 A 出现的 id2。对于 B,id3 是最常见的,所以我想用 id3 替换任何其他实例,这意味着我只想将 B 的 'id' 替换为 'id3'。对于 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']]

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

【问题讨论】:

  • 另外,你打算之后对desired_list 做什么?这可能会影响它应该采用的形式(很可能,为了达到你提到的效率,你需要存储一些比平面值更漂亮的东西)。

标签: python list sublist


【解决方案1】:

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

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]

这已经针对可读性(我认为,很好!)而不是原始速度进行了优化。例如,您可能不想在不需要时写回字典,或者维护一个单独的最大字典以防止最后在列表理解中进行两个键查找。

【讨论】:

    【解决方案2】:

    使用上面的 ad-hoc 要求直接进行数据处理,我可以提出以下算法。

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

    def generate_frequency_table(lst):
        assoc = {}        # e.g. 'A': {'id1': 3, 'id2': 2}
        for key, unused, val in list:
            freqs = assoc.get(key, None)
            if freqs is None:
                freqs = {}
                assoc[key] = freqs
            valfreq = freqs.get(val, None)
            if valfreq is None:
                freqs[val] = 1
            else:
                freqs[val] = valfreq + 1
        return assoc
    
    >>> generate_frequency_table(lst)
    {'A': {'id2': 2, 'id1': 3}, 'C': {'id6': 2, 'id5': 1}, 'B': {'id3': 4, 'id': 1}}
    

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

    def generate_max_assoc(assoc):
        max = {}    # e.g. {'A': 'id1'}
        for key, freqs in assoc.iteritems():
            curmax = ('', 0)
            for val, freq in freqs.iteritems():
                if freq > curmax[1]:
                    curmax = (val, freq)
            max[key] = curmax[0]
        return max
    
    >>> maxtable = generate_max_assoc(generate_frequency_table(lst))
    >>> print maxtable
    {'A': 'id1', 'C': 'id6', 'B': 'id3'}
    

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

    >>> 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']]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多