可变的整形整形

时间:2019-03-29 04:04:26

标签: python list numpy

在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循环,但是似乎无法使索引正常工作。

4 个答案:

答案 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,))