【问题标题】:Merging of two lists following certain patterns [duplicate]遵循某些模式合并两个列表[重复]
【发布时间】:2017-07-19 19:46:01
【问题描述】:

我有两个列表:

a = ['a', 'b', 'c', 'd']
b = ['e', 'f', 'g', 'h']

我想将其合并到一个包含元素 nr 的列表中。列表 a 的 1 作为第一个元素,列表 b 的元素 nr.1 作为第二个元素,元素 nr。列表 a 中的 2 作为第三个元素,依此类推,如下所示:

c = ['a', 'e', 'b', 'f', 'c', 'g', 'd', 'h']

最简单的方法是什么,可能不使用循环?

【问题讨论】:

  • 由于问题已关闭,我将无法发布我的基准测试,但迄今为止最快的答案是 list(sum(zip(a, b), ()))
  • @BPL 期待您的基准测试,请求重新提出问题
  • @很快谢谢!有时管理员应该多花点时间,即使它们是重复的问题……你总能找到一些人发布新的有趣数据,为问题增加价值;)
  • @soon 好的,我有机会发表我的小研究;)。顺便说一句,请求重新回答问题的按钮在哪里?我什至不知道这是可能的(这里的新手)
  • @BPL 您将能够在达到 3k 代表后进行关闭和重新投票。 Docs

标签: python


【解决方案1】:

只需将zip 他们成对,然后使用itertools.chain.from_iterable 将列表展平:

In [1]: a=['a','b','c','d']

In [2]: b=['e','f','g','h']

In [3]: from itertools import chain

In [4]: chain.from_iterable(zip(a, b))
Out[4]: <itertools.chain at 0x7fbcf2335ef0>

In [5]: list(chain.from_iterable(zip(a, b)))
Out[5]: ['a', 'e', 'b', 'f', 'c', 'g', 'd', 'h']

【讨论】:

    【解决方案2】:

    这是一个将一些可能的方法与 2 个不同数据集进行比较的答案,一个由许多小数组组成,另一个由几个大数组组成:

    导入时间 随机导入 从 itertools 导入链

    def f1(a, b):
        return list(chain.from_iterable(zip(a, b)))
    
    
    def f2(a, b):
        return list(sum(zip(a, b), ()))
    
    
    def f3(a, b):
        result = []
        for (e1, e2) in zip(a, b):
            result += [e1, e2]
    
        return result
    
    
    def f4(a, b):
        result = []
        len_result = min(len(a), len(b))
    
        result = []
        i = 0
        while i < len_result:
            result.append(a[i])
            result.append(b[i])
            i += 1
    
        return result
    
    # Small benchmark
    N = 5000000
    a_small = ['a', 'b', 'c', 'd']
    b_small = ['e', 'f', 'g', 'h']
    benchmark1 = [
        timeit.timeit(
            'f1(a_small, b_small)', setup='from __main__ import f1, a_small,b_small', number=N),
        timeit.timeit(
            'f2(a_small, b_small)', setup='from __main__ import f2, a_small,b_small', number=N),
        timeit.timeit(
            'f3(a_small, b_small)', setup='from __main__ import f3, a_small,b_small', number=N),
        timeit.timeit(
            'f4(a_small, b_small)', setup='from __main__ import f4, a_small,b_small', number=N)
    ]
    
    for index, value in enumerate(benchmark1):
        print " - Small sample with {0} elements -> f{1}={2}".format(len(a_small), index + 1, value)
    
    # Large benchmark
    N = 5000
    K = 100000
    P = 1000
    a_large = random.sample(range(K), P)
    b_large = random.sample(range(K), P)
    benchmark2 = [
        timeit.timeit(
            'f1(a_large, b_large)', setup='from __main__ import f1, a_large,b_large', number=N),
        timeit.timeit(
            'f2(a_large, b_large)', setup='from __main__ import f2, a_large,b_large', number=N),
        timeit.timeit(
            'f3(a_large, b_large)', setup='from __main__ import f3, a_large,b_large', number=N),
        timeit.timeit(
            'f4(a_large, b_large)', setup='from __main__ import f4, a_large,b_large', number=N)
    ]
    
    for index, value in enumerate(benchmark2):
        print " - Large sample with {0} elements -> f{1}={2}".format(K, index + 1, value)
    
    • 4 个元素的小样本 -> f1=7.50175959666
    • 4 个元素的小样本 -> f2=5.52386084127
    • 4 个元素的小样本 -> f3=7.12457549607
    • 4 个元素的小样本 -> f4=7.24530968309
    • 100000 个元素的大样本 -> f1=0.512278885906
    • 包含 100000 个元素的大样本 -> f2=28.0679210232
    • 包含 100000 个元素的大样本 -> f3=1.05977378475
    • 100000 个元素的大样本 -> f4=1.17144886156

    结论:当 N 很大并且列表很少时,f2 函数似乎是稍微快一些的方法。当数组很大并且数量很少时,f1 是赢家。

    规格:Python2.7.11(64),在 i-7 2.6Ghz 上 N=5000000

    【讨论】:

    • 能否也为大型列表添加基准?
    • @soon 感谢指出,我已经编辑了我的答案,基准测试现在更完整了一点
    猜你喜欢
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多