【问题标题】:Merge Lists with same first index but other second index合并具有相同第一个索引但其他第二个索引的列表
【发布时间】:2015-12-06 23:10:32
【问题描述】:

我正在研究 python 中的搜索算法,但有些东西我没有开始工作..

我有一个看起来像这样的列表 [["A","1.txt"],["A","2.txt"],["A","3.txt"],[" B","1.txt"],["B","3.txt"]]

现在我想合并具有相同第一个索引的子列表。所以结果是:

[["A",["1.txt","2.txt",3.txt"]],["B",["1.txt"],["3.txt"]] ]

任何知道如何做到这一点的人...... 有点排序(基于合并排序),但这不会合并元组

def merge_pairs(data):
if len(data) <= 1 :
    return data[:]
else:
        mid = len(data) // 2
        fst = merge_pairs(data[:mid])
        snd = merge_pairs(data[mid:])   
        res = []
        fi = 0
        si = 0
        while fi < len(fst) and si < len(snd):
            if fst[fi][0] < snd[si][0] or fst[fi][0] == snd[si][0] and fst[fi][1] < snd[si][1]:
                res.append(fst[fi])
                fi = fi + 1
            else:
                res.append(snd[si])
                si = si + 1
        if fi < len(fst) :
            res.extend(fst[fi:])
        elif si < len(snd) :
            res.extend(snd[si:])
return res

所以我不想使用python的dict()函数

提前致谢

【问题讨论】:

    标签: list sorting python-3.x merge


    【解决方案1】:

    最简单的方法(可能比困难的方法慢也可能不慢)是使用默认字典:

    >>> from collections import defaultdict
    >>> result = defaultdict(list)
    >>> mylist = [["A","1.txt"],["A","2.txt"],["A","3.txt"],["B","1.txt"],["B","3.txt"]]
    >>> for key, value in mylist:
    ...     result[key].append(value)
    ... 
    >>> print(sorted(result.items()))
    [('A', ['1.txt', '2.txt', '3.txt']), ('B', ['1.txt', '3.txt'])]
    

    困难的方式(如果您的数据确实已经排序):

    >>> src = [["A","1.txt"],["A","2.txt"],["A","3.txt"],["B","1.txt"],["B","3.txt"]]
    >>> prev = None
    >>> dst = []
    >>> for key, value in src:
    ...     if key != prev:
    ...         prev = key
    ...         dst.append((key, []))
    ...     dst[-1][-1].append(value)
    ... 
    >>> print(dst)
    [('A', ['1.txt', '2.txt', '3.txt']), ('B', ['1.txt', '3.txt'])]
    

    但请注意,Python 排序真的非常快,而且 Python 循环像这样......没那么多。

    编辑根据您在下面的评论,您还需要计数。还有一种字典方式:

    >>> from collections import defaultdict
    >>> result = defaultdict(lambda: defaultdict(int))
    >>> mylist = [["A","1.txt"],["A","2.txt"],["A", "2.txt"],["A","3.txt"],["B","1.txt"],["B","3.txt"]]
    >>> for key, value in mylist:
    ...     result[key][value] += 1
    ... 
    >>> print(sorted((x, sorted(y.items())) for (x, y) in result.items()))
    [('A', [('1.txt', 1), ('2.txt', 2), ('3.txt', 1)]), ('B', [('1.txt', 1), ('3.txt', 1)])]
    

    和循环方式:

    >>> src = [["A","1.txt"],["A","2.txt"],["A", "2.txt"],["A","3.txt"],["B","1.txt"],["B","3.txt"]]
    >>> prevkey, prevvalue = None, None
    >>> dst = []
    >>> for key, value in src:
    ...     if key != prevkey:
    ...         prevkey = key
    ...         prevvalue = None
    ...         dst.append((key, []))
    ...     if value != prevvalue:
    ...         prevvalue = value
    ...         dst[-1][-1].append([value, 0])
    ...     dst[-1][-1][-1][-1] += 1
    ... 
    >>> dst
    [('A', [['1.txt', 1], ['2.txt', 2], ['3.txt', 1]]), ('B', [['1.txt', 1], ['3.txt', 1]])]
    

    您确实希望运行 timeit 来确定,但在这种情况下,循环方式几乎可以保证更慢(当然,字典方式不需要您进行预排序。)

    【讨论】:

    • 有没有办法在这个元组列表中获得一个计数值。所以: [["A","2.txt"],["A","2.txt"]] 将是 [('A', [ '2.txt, 2')] 而不是 [(' A', ['2.txt')]
    • @MartijnLinders -- 我已经用这个更新了答案,所以请编辑你的问题以在最后提出这个问题,以便我的答案与问题正确匹配,然后在它看起来可以接受的情况下接受答案。
    猜你喜欢
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 2021-08-28
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多