将列表压缩为重复的字符串

时间:2018-06-13 13:41:53

标签: python python-3.x list iteration

逻辑:将列表压缩为一个字符串,其中在列表中重复两次的字母在结果字符串中重复指定的次数。

示例:

  • ['a','a',2,'b','c','c',3], - > aabccc
  • ['a,','a',2] - > aa
  • ['c','c',3] - > ccc

我的代码是:

def run_length_decoder(in_list):
list=[]
for i in range(0,len(in_list)-1):
    if in_list[i]==in_list[i+1]:
        for x in range((i+2)-1):
            list.append(in_list[i])
    else:
        list.append(in_list[i])
list.append(in_list[-1])
word = ""
for letter in list:
    word += str(letter)
return word

这不起作用...因为使用['a', 'a', 2, 'b', 'b', 2, 'a', 'b', 'a']运行上述内容会返回'aaa2bbbbbb2aba',但应该返回'aabbaba'

3 个答案:

答案 0 :(得分:1)

似乎很复杂。对于初学者,你应该纠正缩进。此外,由于具有数字计数器是可选的,因此您需要添加逻辑以识别整数与字符串。最后,由于字母数不需要与下面的计数器同步,您需要明确地在每个计数器上附加一个字母。

您可以通过itertools.groupby和列表理解来实现此目的。

from itertools import groupby, zip_longest

L = ['a', 'a', 2, 'b', 'b', 2, 'a', 'b', 'a']

L2 = [i for i, _ in groupby(L)]

res = ''.join([i*(j if isinstance(j, int) else 1)
               for i, j in zip_longest(L2, L2[1:])
               if isinstance(i, str)])

print(res)

aabbaba

答案 1 :(得分:0)

您可以使用while

itertools.groupby循环中使用解压缩功能
import itertools
def group_data(f):
  def wrapper(_s):
    return list(f([[a, list(b)] for a, b in itertools.groupby(_s, key=lambda x:isinstance(x, str))]))
  return wrapper

@group_data
def decompress(stream): 
  while stream:
    if len(stream) == 1:
       [[_, v]] = stream
       yield v
       stream = []
    else:
       [flag, a], [flag2, b], *_stream = stream
       if flag and not flag2:
         yield a if b[0] ==2 else [a[-1]]*b[0] if len(set(a)) == 1 else [*a[:-1], *([a[-1]]*b[0])]
         stream = _stream
       else:
         yield a
         stream = [[flag, b], *_stream]

data = [['a', 'a', 2, 'b', 'b', 2, 'a', 'b', 'a'], ['a', 'a', 3, 'b', 'b', 2, 'a', 'b', 'a', 3]]
new_result = list(map(lambda x:''.join(''.join(i) for i in decompress(x)), data))

输出:

['aabbaba', 'aaabbabaaa']

答案 2 :(得分:0)

使用生成器功能:

def repeat(x):
    def _repeat(x):
        it = iter(x)
        last = nxt = next(it)
        yield last
        while it:
            try:
                last = nxt
                nxt = next(it)
            except StopIteration:
                # See PEP 479 / new handling in Python 3.5
                break
            if isinstance(nxt, str):
                yield nxt
            elif isinstance(nxt, int):
                rpt = nxt - 2
                if rpt:
                    yield last * rpt
    return ''.join(_repeat(x))

>>> x = ['a', 'a', 2, 'b', 'c', 'c', 3]
>>> repeat(x)
'aabccc'

>>> y = ['a', 'a', 2, 'b', 'b', 2, 'a', 'b', 'a']
>>> repeat(y)
'aabbaba'

>>> repeat(['c', 'c', 3])
'ccc'

内部函数说,"继续前进/屈服,直到你点击int n 。"当它被击中时,重复上一个字符 n - 2 次。

从Python 3.5开始,StopIteration显式checking