展开具有相同元素的列表

假设我有以下嵌套列表:


initial_list = [[1, 2, 3],

                [4, 5, 6],

                [7, 8, 9]]

我想把它变成以下:


desired_list = [[1, 1, 1, 2, 2, 2, 3, 3, 3], 

                [4, 4, 4, 5, 5, 5, 6, 6, 6], 

                [7, 7, 7, 8, 8, 8, 9, 9, 9]]

如果我不关心订单,我可以做类似的事情


new_list = [sorted(x*3) for x in initial_list]

但是,顺序应与initial_list. 我能做的最好的是将每个元素放在一个列表中并将其乘以 3(任意数),然后加入结果inner_list:


multiplied_list = [[[element]*3 for element in inner_list] for inner_list in initial_list]

desired_list = [[element for element_list in inner_list for element in element_list] for inner_list in multiplied_list]

(在人类理解的两个列表中)


是否有更易于理解/充分/pythonic 的方式来执行此操作?


一只甜甜圈
浏览 86回答 4
4回答

侃侃尔雅

您可以只使用以下列表理解。请注意,我initial_list与 OP 中的不同,以证明保留了订单。代码:>>> initial_list = [[1, 3, 2], [4, 5, 6], [7, 8, 9]]>>> [[x for x in sl for _ in range(3)] for sl in initial_list][[1, 1, 1, 3, 3, 3, 2, 2, 2], [4, 4, 4, 5, 5, 5, 6, 6, 6], [7, 7, 7, 8, 8, 8, 9, 9, 9]]或者,在您的示例中向 sorted 函数添加一个键:>>> [sorted(x*3, key=x.index) for x in initial_list][[1, 1, 1, 3, 3, 3, 2, 2, 2], [4, 4, 4, 5, 5, 5, 6, 6, 6], [7, 7, 7, 8, 8, 8, 9, 9, 9]]具有不同 n*n 列表大小的方法的时间比较:使用perfplot生成- 代码重现:from itertools import chainfrom functools import reduceimport perfplotfrom copy import deepcopyimport numpy as npimport randomdef shuffle(x):    random.shuffle(x)    return xdef cdjb(initial_list):    return [[x for x in sl for _ in range(3)] for sl in initial_list]def aurora_sorted(initial_list):    return [sorted(x*3, key=x.index) for x in initial_list]def aurora_list_comp(initial_list):    return [[element for element_list in inner_list for element in element_list] for inner_list in [[[element]*3 for element in inner_list] for inner_list in initial_list]]def kederrac(initial_list):    new_list = deepcopy(initial_list)    for l in new_list:        for j in range(0, 3*len(l), 3):            l[j: j + 1] = [l[j]] * 3    return new_listdef alain_chain(initial_list):    return [list(chain(*(i3 for i3 in zip(*[sl]*3)))) for sl in initial_list]def alain_reduce(initial_list):    return [list(reduce(lambda a,e:a+[e]*3,sl,[]))for sl in initial_list]def alain_zip(initial_list):    return [[i for i3 in zip(*[sl]*3) for i in i3] for sl in initial_list]def binyamin_numpy(initial_list):    return np.array(initial_list).repeat(3).reshape(len(initial_list), -1).tolist()perfplot.show(    setup=lambda n: [shuffle([i for i in range(n)]) for j in range(n)],    n_range=[2**k for k in range(12)],    kernels=[        cdjb,aurora_sorted, aurora_list_comp, kederrac, alain_chain, alain_reduce, alain_zip, binyamin_numpy        ],    xlabel='len(x)',    )

弑天下

numpy 和 1 行代码: arr=np.array(initial_list)  arr.repeat(3).reshape(3,-1)输出:Out[44]: array([[1, 1, 1, 2, 2, 2, 3, 3, 3],        [4, 4, 4, 5, 5, 5, 6, 6, 6],        [7, 7, 7, 8, 8, 8, 9, 9, 9]])

aluckdog

这是一个使用 2 个 for 循环的简单示例:for l in initial_list:    for j in range(0, 3*len(l), 3):        l[j: j + 1] = [l[j]] * 3我一直在测试@CDJB 解决方案(带排序):from random import choicedef test1():    initial_list = [[choice(range(1000)) for _ in range(1000)] for _ in range(100)]     def my_func(initial_list):        for l in initial_list:            for j in range(0, 3*len(l), 3):                l[j: j + 1] = [l[j]] * 3        return initial_list    my_func(initial_list)def test2():    initial_list = [[choice(range(1000)) for _ in range(1000)] for _ in range(100)]      [sorted(x*3, key=x.index) for x in initial_list]结果如下:%timeit test2()1.55 s ± 5.12 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)和:%timeit test1()165 ms ± 542 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)这个简单的解决方案快 9 倍,当然取决于您的数据

临摹微笑

您可以使用 zip 和 chain(来自 itertools)来做到这一点:  from itertools import chain  aList  = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]   aList3 = [ list(chain(*(i3 for i3 in zip(*[sl]*3)))) for sl in aList ]或使用 functools 中的 reduce (在较大的列表中速度要慢得多):  from functools import reduce  aList  = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  aList3 = [ list(reduce(lambda a,e:a+[e]*3,sl,[]))for sl in aList ]或带有嵌套理解的 zip(比链式压缩要快一点):  aList  = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]  aList3 = [[i for i3 in zip(*[sl]*3) for i in i3] for sl in initial_list]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python