在Python中解压缩数组

0 投票
4 回答
902 浏览
提问于 2025-04-17 19:59

我需要解压一个数组,但不知道从哪里开始。

这是函数的输入:

def main():
    # Test case for Decompress function
    B = [6, 2, 7, 1, 3, 5, 1, 9, 2, 0]
    A = Decompress(B)
    print(A)

我希望输出是这样的:

A = [2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 9, 0, 0]

如果你看不懂这个规律,B[1] 表示 B[2]A[] 中出现的次数,接着 B[3] 表示 B[4]A[] 中出现的次数,依此类推。

我该怎么写一个函数来实现这个呢?

4 个回答

0

再来一个简单的一行代码:

def decompress(vl):
    return sum([vl[i] * [vl[i+1]] for i in xrange(0, len(vl), 2)], [])
  1. 这个列表推导式提取并解包成对的数据(xrange(0, len(vl), 2) 是用来遍历成对数据的起始位置,vl[i] 是重复的次数,vl[i+1] 是要重复的内容)。

  2. sum() 把结果合并在一起([] 是一开始的值,解包后的列表会依次加到这里面)。

3

这里有一个简化版,使用了 zip()itertools.chain.from_iterable

from itertools import chain

list(chain.from_iterable([v] * c for c, v in zip(*([iter(B)]*2))))

示例:

>>> B = [6, 2, 7, 1, 3, 5, 1, 9, 2, 0]
>>> from itertools import chain
>>> list(chain.from_iterable([v] * c for c, v in zip(*([iter(B)]*2))))
[2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 9, 0, 0]

我们来分解一下这个过程:

  • zip(*([iter(B)]*2))) 将计数和对应的值配对:

    >>> zip(*([iter(B)]*2))
    [(6, 2), (7, 1), (3, 5), (1, 9), (2, 0)]
    

    这是一个相当常见的 Python 技巧,用来从输入的可迭代对象中获取成对的数据。

  • ([v] * c for c, v in zip(*([iter(B)]*2))) 是一个生成器表达式,它将计数和对应的值结合起来,生成一个列表,列表中每个值会重复计数次:

    >>> next([v] * c for c, v in zip(*([iter(B)]*2)))
    [2, 2, 2, 2, 2, 2]
    
  • chain.from_iterable 会把生成器表达式产生的多个列表合并,让你可以像处理一个长列表一样遍历它们。

  • list() 最后将所有内容转换回一个列表。

1

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这就像把水从一个杯子倒到另一个杯子一样。

有些时候,我们会遇到一些问题,比如数据的格式不对,或者我们想要的数据没有被正确地获取到。这就像你想喝水,但杯子里却是果汁,这时候你就需要先把果汁倒掉,再去装水。

在解决这些问题时,我们可能会用到一些工具和方法,就像在厨房里用不同的器具来做饭一样。每种工具都有它的用途,选择合适的工具能让我们的工作更轻松。

总之,编程就像是在做一件复杂的事情,我们需要耐心和细心,才能把每一步都做好。

def unencodeRLE(i):
    i = list(i) #Copies the list to a new list, so the original one is not changed.
    r = []

    while i:
        count = i.pop(0)
        n = i.pop(0)
        r+= [n for _ in xrange(count)]
    return r

撰写回答