亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

展開具有相同元素的列表

展開具有相同元素的列表

一只甜甜圈 2022-07-19 10:29:03
假設我有以下嵌套列表: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 的方式來執行此操作?
查看完整描述

4 回答

?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

您可以只使用以下列表理解。請注意,我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 列表大小的方法的時間比較:

http://img1.sycdn.imooc.com//62d6170f0001e68405640379.jpg

使用perfplot生成- 代碼重現:


from itertools import chain

from functools import reduce

import perfplot

from copy import deepcopy

import numpy as np

import random


def shuffle(x):

    random.shuffle(x)

    return x


def 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_list


def 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)',

    )


查看完整回答
反對 回復 2022-07-19
?
弒天下

TA貢獻1818條經驗 獲得超8個贊

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


查看完整回答
反對 回復 2022-07-19
?
aluckdog

TA貢獻1847條經驗 獲得超7個贊

這是一個使用 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 choice

def 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 倍,當然取決于您的數據


查看完整回答
反對 回復 2022-07-19
?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

您可以使用 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]


查看完整回答
反對 回復 2022-07-19
  • 4 回答
  • 0 關注
  • 112 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號