在Python中,我有一个需要根据另一个数组中的值分解成较小数组的值列表。例如,我有以下数字数组:
[6,5,3,1,4,3,2,4,1,3,6,1]
我需要它来变成这个数组:
[[6,5,3],[1,4],[3,2],[4],[1,3,6],[1]]
鉴于我有这个数组来指定分解部分的长度:
[3,2,2,1,3,1]
我尝试查看numpy重塑文档,并且此函数似乎可以实现我想要的功能,但是我不确定如何在不修改整个数组并本质上以“可变”方式进行操作的情况下使其工作。我也尝试过for循环,但是似乎无法使索引正常工作。
答案 0 :(得分:1)
如果您不想承担从列表中删除项目的额外费用,这是使用itertools.islice()
的一种方法:
iterator = iter(my_list)
my_result = [list(islice(iterator, length)) for length in my_lens]
进行测试:
from itertools import islice
my_list = [6,5,3,1,4,3,2,4,1,3,6,1]
my_lens = [3,2,2,1,3,1]
iterator = iter(my_list)
my_result = [list(islice(iterator, length)) for length in my_lens]
print(my_result)
输出:
[[6, 5, 3], [1, 4], [3, 2], [4], [1, 3, 6], [1]]
答案 1 :(得分:0)
假设长度总和始终与列表长度相同,则可以使用list.pop(0)
:
l = [6,5,3,1,4,3,2,4,1,3,6,1]
[[l.pop(0) for _ in range(i)] for i in [3,2,2,1,3,1]]
输出:
[[6, 5, 3], [1, 4], [3, 2], [4], [1, 3, 6], [1]]
注意:默认情况下,list.pop
会弹出 last 元素,因此将使用list.pop(0)
。
答案 2 :(得分:0)
如果您需要对许多列表执行此过程,则最好具有一个预制函数。这是一个完全使用HigherOrderPython编写的。
from itertools import accumulate, tee, chain
from operator import itemgetter
i2, i3 = tee(accumulate([3, 2, 2, 1, 3, 2]))
slicer = itemgetter(*map(slice, chain([None], i2), i3))
>>> print(slicer([6, 5, 3, 1, 4, 3, 2, 4, 1, 3, 6, 1]))
([6, 5, 3], [1, 4], [3, 2], [4], [1, 3, 6], [1])
答案 3 :(得分:0)
使用发生器的解决方案如下。
def splitter(arr, lengths):
assert(sum(lengths) == len(arr))
i, s = 0, 0
for l in lengths:
s = s + l
yield arr[i:s]
i = i + l
它提供了更多的灵活性-输入几乎可以是任何序列(列表,元组,字符串等),而输出可以转换为任何合适的序列。
my_list = [6, 5, 3, 1, 4, 3, 2, 4, 1, 3, 6, 1]
my_lens = [3, 2, 2, 1, 3, 1]
ans = [x for x in splitter(my_list, my_lens)]
print(ans)
# [[6, 5, 3], [1, 4], [3, 2], [4], [1, 3, 6], [1]]
text = 'a quick brown fox jumped over the lazy dog'
lengths = [2, 6, 6, 4, 7, 5, 4, 5, 3]
print([x for x in splitter(text, lengths)])
# ['a ', 'quick ', 'brown ', 'fox ', 'jumped ', 'over ', 'the ', 'lazy ', 'dog']
my_tuple = (6, 5, 3, 1, 4, 3, 2, 4, 1, 3, 6, 1)
my_lens = [3, 2, 2, 1, 3, 1]
print(tuple(x for x in splitter(my_tuple, my_lens)))
# ((6, 5, 3), (1, 4), (3, 2), (4,), (1, 3, 6), (1,))