我还是Python的新手,并且在编程中学习更基本的东西。 现在我正在尝试创建一个能够复制一组数字的功能,这些功能各不相同。
示例:
def expand('d3f4e2')
>dddffffee
我不确定如何为此编写功能。 基本上我理解你想把字母变量加到它旁边的数字变量上。
答案 0 :(得分:2)
任何解决方案的关键是将事物分成要重复的字符串对,重复计数,然后以锁定步骤迭代这些对。
如果您只需要单字符字符串和单位数重复计数,这只是将字符串分成2个字符对,您可以使用mshsayem的答案或切片({{1是字符串,s[::2]
是计数。)
但是如果你想将它概括为多字母字符串和多位数呢?
好吧,不知何故,我们需要将字符串分组为数字和非数字的运行。如果我们能够做到这一点,我们可以使用这些组的对,mshsayem的答案使用完全相同的方式。
事实证明我们可以很容易地做到这一点。标准库中有一个名为groupby
的漂亮函数,可以根据任何函数将任何内容分组到运行中。并且有一个函数isdigit
可以区分数字和非数字。
所以,这会让我们得到我们想要的运行:
s[1::2]
现在我们将其压缩起来的方式与mshsayem压缩字符相同:
>>> import itertools
>>> s = 'd13fx4e2'
>>> [''.join(group) for (key, group) in itertools.groupby(s, str.isdigit)]
['d', '13', 'ff', '4', 'e', '2']
所以:
>>> groups = (''.join(group) for (key, group) in itertools.groupby(s, str.isdigit))
>>> ''.join(c*int(d) for (c, d) in zip(groups, groups))
'dddddddddddddfxfxfxfxee'
答案 1 :(得分:1)
天真的方法(如果数字只是单个,字符也是单个):
>>> def expand(s):
s = iter(s)
return "".join(c*int(d) for (c,d) in zip(s,s))
>>> expand("d3s5")
'dddsssss'
解释不好:
条款/功能:
iter()
会为您提供iterator个对象。zip()
从iterables中获取tuples。int()
解析字符串<expression> for <variable> in <iterable>
是list comprehension <string>.join
使用string
过程:
zip()
被用来制作角色元组和重复次数。例如('d','3'), ('s','5)
(zip()
将调用iterable来生成元组。请注意,对于每个元组,它将调用相同的iterable两次 - 因为我们的iterable是迭代器,这意味着它将前进两次) for in
将迭代元组。使用两个变量(c,d)
会将元组解压缩为那些d
仍然是一个字符串。 int
正在使它成为整数<string> * integer
会以string
次integer
join
将返回结果这是一个多位数的多字符版本:
import re
def expand(s):
s = re.findall('([^0-9]+)(\d+)',s)
return "".join(c*int(d) for (c,d) in s)
顺便说一句,使用itertools.groupby
会更好,shown by abarnert。
答案 2 :(得分:0)
让我们看一下如何使用新手可以理解的工具手动完成此操作。实际了解zip
以及迭代器和理解等等更好,但它可能也有助于看到你写同样东西的笨拙和冗长的方式
所以,让我们从单个字符和单个数字开始:
def expand(s):
result = ''
repeated_char_next = True
for char in s:
if repeated_char_next:
char_to_repeat = char
repeated_char_next = False
else:
repeat_count = int(char)
s += char_to_repeat * repeat_count
repeated_char_next = True
return char
这是一个非常简单的状态机。有两种状态:下一个字符是要重复的字符,或者是一个给出重复计数的数字。阅读前者之后,我们还没有任何补充(我们知道角色,但不知道重复多少次),所以我们所做的就是切换状态。在阅读后者之后,我们现在知道要添加什么(因为我们知道字符和重复计数),所以我们这样做,并且还切换状态。这就是它的全部内容。
现在,将它扩展为多字符重复字符串和多位重复计数:
def expand(s):
result = ''
current_repeat_string = ''
current_repeat_count = ''
for char in s:
if isdigit(char):
current_repeat_count += char
else:
if current_repeat_count:
# We've just switched from a digit back to a non-digit
count = int(current_repeat_count)
result += current_repeat_string * count
current_repeat_count = ''
current_repeat_string = ''
current_repeat_string += char
return char
这里的状态非常相似 - 我们要么在读取非数字,要么在读数字的中间。但是我们不会在每个角色后自动切换状态;我们只在非数字后得到一个数字时才这样做,反之亦然。另外,我们必须跟踪当前重复字符串和当前重复计数中的所有字符。我已经将状态标志折叠成了重复的字符串,但这里没有其他任何棘手的问题。
答案 3 :(得分:0)
执行此操作的方法不止一种,但假设输入中的字符序列始终相同,例如:单个字符后跟数字,以下内容可以正常工作
def expand(input):
alphatest = False
finalexpanded = "" #Blank string variable to hold final output
#first part is used for iterating through range of size i
#this solution assumes you have a numeric character coming after your
#alphabetic character every time
for i in input:
if alphatest == True:
i = int(i) #converts the string number to an integer
for value in range(0,i): #loops through range of size i
finalexpanded += alphatemp #adds your alphabetic character to string
alphatest = False #Once loop is finished resets your alphatest variable to False
i = str(i) #converts i back to string to avoid error from i.isalpha() test
if i.isalpha(): #tests i to see if it is an alphabetic character
alphatemp = i #sets alphatemp to i for loop above
alphatest = True #sets alphatest True for loop above
print finalexpanded #prints the final result