我刚刚开始学习python,我有一个让我困惑的练习:创建一个可以打包或解压一串字母的函数。所以aaabb会被包装成a3b2,反之亦然。
对于函数的打包部分,我编写了以下内容
def packer(s):
if s.isalpha(): # Defines if unpacked
stack = []
for i in s:
if s.count(i) > 1:
if (i + str(s.count(i))) not in stack:
stack.append(i + str(s.count(i)))
else:
stack.append(i)
print "".join(stack)
else:
print "Something's not quite right.."
return False
packer("aaaaaaaaaaaabbbccccd")这一切似乎都很合适。但是赋值说,如果输入有(例如)字母a后的b或c,那么它以后应该被解压成原来的形式。所以"aaabbkka“应该变成a3b2k2a,而不是a4b2k2。因此,我想,我不能使用"count()“命令,因为这会将整个字符串中的所有项计数,对吗?那么我在这里有什么选择呢?
关于解压-我已经想到了我的代码需要做的基本工作-
大问题2-我如何检查它是一个数字还是一个字母元素后面的一个元素在列表中?我想这必须通过切片来完成,但是那些只需要整数。这能用index命令实现吗?
此外--如果这与此相关--到目前为止,我基本上已经讨论了列表、字符串、if和for --有人告诉我,这个练习只适用于那些(...so,如果您不介意保持这个非常基本的)
所有的帮助感谢新手爱好者!
已解决:
def packer(s):
if s.isalpha(): # Defines if unpacked
groups= []
last_char = None
for c in s:
if c == last_char:
groups[-1].append(c)
else:
groups.append([c])
last_char = c
return ''.join('%s%s' % (g[0], len(g)>1 and len(g) or '') for g in groups)
else: # Seems to be packed
stack = ""
for i in range(len(s)):
if s[i].isalpha():
if i+1 < len(s) and s[i+1].isdigit():
digit = s[i+1]
char = s[i]
i += 2
while i < len(s) and s[i].isdigit():
digit +=s[i]
i+=1
stack += char * int(digit)
else:
stack+= s[i]
else:
""
return "".join(stack)
print (packer("aaaaaaaaaaaabbbccccd"))
print (packer("a4b19am4nmba22")) 这是我的最后密码。几乎成功地用for循环和if语句实现了这一切。最后,我不得不引入while循环来解决读取多位数的问题。我想我还是把它保持得够简单了。谢谢一吨的马鹿和其他人的插嘴!
发布于 2013-09-22 12:32:59
一个简单的解决方案:如果一个字符是不同的,那么创建一个新的组。否则,将其附加到最后一组。最后,数数所有的小组,并加入他们。
def packer(s):
groups = []
last_char = None
for c in s:
if c == last_char:
groups[-1].append(c)
else:
groups.append([c])
last_char = c
return ''.join('%s%s'%(g[0], len(g)) for g in groups)另一种方法是使用re。
Regex r'(.)\1+'可以匹配超过1的连续字符。使用re.sub,您可以轻松地对其进行编码:
regex = re.compile(r'(.)\1+')
def replacer(match):
return match.group(1) + str(len(match.group(0)))
regex.sub(replacer, 'aaabbkka')
#=> 'a3b2k2a'发布于 2013-09-22 11:43:43
我想你可以使用`itertools.grouby的函数
例如
import itertools
data = 'aaassaaasssddee'
groupped_data = ((c, len(list(g))) for c, g in itertools.groupby(data))
result = ''.join(c + (str(n) if n > 1 else '') for c, n in groupped_data)当然,使用生成器而不是生成器语句可以提高代码的可读性。
发布于 2013-09-22 13:15:22
这是我在评论中概述的算法的一个实现:
from itertools import takewhile, count, islice, izip
def consume(items):
from collections import deque
deque(items, maxlen=0)
def ilen(items):
result = count()
consume(izip(items, result))
return next(result)
def pack_or_unpack(data):
start = 0
result = []
while start < len(data):
if data[start].isdigit():
# `data` is packed, bail
return unpack(data)
run = run_len(data, start)
# append the character that might repeat
result.append(data[start])
if run > 1:
# append the length of the run of characters
result.append(str(run))
start += run
return ''.join(result)
def run_len(data, start):
"""Return the end index of the run of identical characters starting at
`start`"""
return start + ilen(takewhile(lambda c: c == data[start],
islice(data, start, None)))
def unpack(data):
result = []
for i in range(len(data)):
if data[i].isdigit():
# skip digits, we'll look for them below
continue
# packed character
c = data[i]
# number of repetitions
n = 1
if (i+1) < len(data) and data[i+1].isdigit():
# if the next character is a digit, grab all the digits in the
# substring starting at i+1
n = int(''.join(takewhile(str.isdigit, data[i+1:])))
# append the repeated character
result.append(c*n) # multiplying a string with a number repeats it
return ''.join(result)
print pack_or_unpack('aaabbc')
print pack_or_unpack('a3b2c')
print pack_or_unpack('a10')
print pack_or_unpack('b5c5')
print pack_or_unpack('abc')unpack()的正则化版本将是:
import re
UNPACK_RE = re.compile(r'(?P<char> [a-zA-Z]) (?P<count> \d+)?', re.VERBOSE)
def unpack_re(data):
matches = UNPACK_RE.finditer(data)
pairs = ((m.group('char'), m.group('count')) for m in matches)
return ''.join(char * (int(count) if count else 1)
for char, count in pairs)此代码演示了实现该算法的最直接(或“基本”)方法。它并不特别优雅,不地道,也不一定有效率。(如果是用C编写的话,但是Python有这样的警告:索引字符串将字符复制到一个新的字符串中,如果复制是用C语言进行的,并且使用Python循环实现的话,似乎过度复制数据的算法可能比试图避免这种复制更快。)
https://stackoverflow.com/questions/18943397
复制相似问题