考虑到以下问题,在Python中执行此操作的最有效(或合理有效)方法是什么:
问题。鉴于列表清单,
L = [list_0, list_1, list_2, list_3, ..., list_n]
其中len(list_i)< = 3,假设L内的每个列表。我们如何将L分成L_1,L_2,L_3,其中L_1只有长度为1的列表,L_2只有长度为2的列表,L_3只有3个长度列表?
潜在的解决方案。这是我能做的最好的事情;我也在这里也包括了一个样本集。它在我的电脑上运行大约8.6秒。
import time
# These 4 lines make a large sample list-of-list to test on.
asc_sample0 = [[i] for i in range(500)]
asc_sample1 = [[i,j] for i in range(500) for j in range(20)]
asc_sample2 = [[i,j,k] for i in range(20) for j in range(10) for k in range(20)]
asc_sample = asc_sample0 + asc_sample1 + asc_sample2
start = time.clock()
cells0 = [i for i in asc if len(i) == 1]
cells1 = [i for i in asc if len(i) == 2]
cells2 = [i for i in asc if len(i) == 3]
print time.clock() - start
我还尝试关闭“弹出”元素并附加到列表cell0等,但这花费的时间要长得多。我还试图追加然后删除那个元素,这样我就可以在一个循环中完成,当有10 ^ 10个大小为1的列表,但只有少数大小为2和3时,但是,通常,效率不高。
我非常欣赏一些巧妙的想法。我知道其中一个答案很可能是“用C语言编写”,但是现在我只想看看Python解决方案。
答案 0 :(得分:2)
旧式解决方案在这里可能会更好用:
cells0, cells1, cells2 = [], [], []
for lst in asc_sample:
n = len(lst)
if n == 1:
cells0.append(lst)
elif n == 2:
cells1.append(lst)
else:
cells2.append(lst)
答案 1 :(得分:1)
这绝对是最好的之一,因为它并行运行。您应该看到的另一件事是itertools.groupby
和内置filter
方法。
答案 2 :(得分:1)
result = dict()
for lst in L:
result.setdefault(len(lst), []).append(lst)
print result
<强>输出强>
{
1: [[0], [1], [2], [3]],
2: [[0, 0], [0, 1], [0, 2]],
3: [[0, 0, 0], [0, 0, 1], [0, 0, 2]]
}
答案 3 :(得分:1)
索引列表/元组应该比执行密钥查找更快。这比问题中给出的版本快约30%
cells = [],[],[],[] # first list here isn't used, but it's handy for the second version
for i in asc:
cells[len(i)].append(i)
通过提取附加方法再次快一点(在较大的列表中,这几乎是OP的两倍)
cells = [],[],[],[]
appends = [x.append for x in cells]
for i in asc:
appends[len(i)](i)