繁体   English   中英

Python:使用dict加速排序元组列表

[英]Python: using a dict to speed sorting of a list of tuples

出于某种原因,我一直在“如何排序这个元组列表”的问题。 (我的先前问题: 按任意键排序元组列表 )。

这是一些任意的原始输入:

number_of = 3  # or whatever
tuple_list = [(n, 'a', 'b', 'c') for n in xrange(number_of)]  # [(0, 'a', 'b', 'c')...]
ordering_list = random.sample(range(number_of), number_of)  # e.g. [1, 0, 2]

排序tuple_list通过ordering_list使用排序:

ordered = sorted(tuple_list, key=lambda t: ordering_list.index(t[0]))
# ordered = [(1, 'a', 'b', 'c'), (0, 'a', 'b', 'c'), (2, 'a', 'b', 'c')]

我有一个稍微尴尬的方法似乎要快得多,特别是随着tuple_list中元素数量的增加。 我创建了一个字典,将tuple分解为字典list_dict (tuple[0], tuple[1:])项。 我使用ordering_list作为键检索字典项,然后将(tuple[0], tuple[1:])的序列重新组合成元组列表,使用成语我仍然试图完全包裹我的头: zip(*[iter(_list)] * x)其中x是由_list的项组成的每个元组的长度。 所以我的问题是:这种方法的版本是否管理反汇编 - 更好地重新组合代码的一部分?

def gen_key_then_values(key_list, list_dict):
    for key in key_list:
        values = list_dict[key]
        yield key

        for n in values:
            yield n

list_dict = {t[0]: t[1:] for t in tuple_list}
ordered = zip(*[gen_key_then_values(ordering_list, list_dict)] * 4)

注意更好的代码,使用Steve Jessop的明显评论如下:

list_dict = {t[0]: t for t in tuple_list}
ordered = [list_dict[k] for k in ordering_list]

我的实际项目代码仍然需要为从list_dict检索到的每个(k, ['a', 'b' ...])项目组合一个元组,但我没有理由在此处包含该部分代码。

在字典中tuple_list的元素并不能真正获得任何东西,并且需要为值创建更多的元组。 您所做的只是根据它们的第一个元素查找列表中的元素,因此可能不值得实际拆分它们:

list_dict = { t[0] : t for t in tuple_list }

请注意,这仅在第一个元素是唯一的时才有效,但是如果第一个元素是唯一的,那么ordering_list才有意义,所以这可能没问题。

zip(*[iter(_list)] * 4)只是一种将_list分组为四肢的方法,所以给它一个合适的名字,你不必担心它:

def fixed_size_groups(n, iterable):
    return zip(*[iter(iterable)] * n)

但是所有事情都认为你实际上并不需要它:

ordered = list(list_dict[val] for val in ordering_list)

你的第一个代码很慢的原因是ordering_list.index很慢 - 它在ordering_list搜索t[0] ,并为每个t执行一次。 所以它总共(number_of ** 2) / 2检查列表元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM