我有以下字符串,并对其进行了拆分:
>>> st = '%2g%k%3p'
>>> l = filter(None, st.split('%'))
>>> print l
['2g', 'k', '3p']
现在我想要打印两次字母 g,一次字母 k 和三次字母 p。ggkppp
怎么可能呢?
isdigit()
的 generator
来检查你的第一个字符是否为数字,然后根据适当的计数返回以下字符串。 然后,您可以使用join
来获得输出:
你可以使用 generator
和 isdigit()
来检查你的首个字符是否为数字,并根据相应的计数返回以下字符串。之后,你可以使用 join
来获取你的输出:
''.join(i[1:]*int(i[0]) if i[0].isdigit() else i for i in l)
演示:
In [70]: [i[1:]*int(i[0]) if i[0].isdigit() else i for i in l ]
Out[70]: ['gg', 'k', 'ppp']
In [71]: ''.join(i[1:]*int(i[0]) if i[0].isdigit() else i for i in l)
Out[71]: 'ggkppp'
编辑
当第一个数字为多位数时,使用re
模块:
''.join(re.search('(\d+)(\w+)', i).group(2)*int(re.search('(\d+)(\w+)', i).group(1)) if re.search('(\d+)(\w+)', i) else i for i in l)
例子:
In [144]: l = ['12g', '2kd', 'h', '3p']
In [145]: ''.join(re.search('(\d+)(\w+)', i).group(2)*int(re.search('(\d+)(\w+)', i).group(1)) if re.search('(\d+)(\w+)', i) else i for i in l)
Out[145]: 'ggggggggggggkdkdhppp'
编辑2
对于您的输入,例如:
st = '%2g_%3k%3p'
你可以将_
替换为空字符串,然后如果列表中的单词以_
符号结尾,则在末尾添加_
。st = '%2g_%3k%3p'
l = list(filter(None, st.split('%')))
''.join((re.search('(\d+)(\w+)', i).group(2)*int(re.search('(\d+)(\w+)', i).group(1))).replace("_", "") + '_' * i.endswith('_') if re.search('(\d+)(\w+)', i) else i for i in l)
输出:
'gg_kkkppp'
编辑3
解决方案没有使用re
模块,但使用适用于2位数字的常规循环。您可以定义函数:
def add_str(ind, st):
if not st.endswith('_'):
return st[ind:] * int(st[:ind])
else:
return st[ind:-1] * int(st[:ind]) + '_'
def collect(l):
final_str = ''
for i in l:
if i[0].isdigit():
if i[1].isdigit():
final_str += add_str(2, i)
else:
final_str += add_str(1, i)
else:
final_str += i
return final_str
然后将它们用作:
l = ['12g_', '3k', '3p']
print(collect(l))
gggggggggggg_kkkppp
''.join(i[1:]*int(i[0]) if i[0].isdigit() else i for i in ['12g', 'k', '3p'])
= '2gkppp'
- Sayse_
进行这种行为吗? - Anton Protopopov一行正则表达式实现:
>>> import re
>>> st = '%2g%k%3p'
>>> re.sub(r'%|(\d*)(\w+)', lambda m: int(m.group(1))*m.group(2) if m.group(1) else m.group(2), st)
'ggkppp'
%|(\d*)(\w+)
正则表达式匹配所有的 %
,并将任何单词字符之前出现的零个或多个数字捕获到一个组中,并将随后的单词字符捕获到另一个组中。 当替换时,所有匹配的字符都应替换为替换部分中给定的值。 因此,应该删除这些匹配的 %
字符。
或者
>>> re.sub(r'%(\d*)(\w+)', lambda m: int(m.group(1))*m.group(2) if m.group(1) else m.group(2), st)
'ggkppp'
\b
吗?因为我觉得它不是必要的。 - Iron Fistre.sub(r'%(\d*)(\w*)', '-RE-',st)
---> '-RE--RE--RE-'
- Iron Fistr'%(\d*)([a-z]+)'
- Avinash Raj假设您总是打印单个字母,但以前的数字可能比十进制中的单个数字更长。
seq = ['2g', 'k', '3p']
result = ''.join(int(s[:-1] or 1) * s[-1] for s in seq)
assert result == "ggkppp"
result = ''.join([int(s[:-1] or 1) * s[-1] for s in st.split('%') if s])
。你可以给.join
一个生成器表达式,但实际上给它一个列表推导更有效率。.join
必须解析其输入两次:第一遍确定输出字符串的大小,第二遍构建输出。因此,如果你给.join
一个生成器表达式,它必须运行生成器并从中构建一个列表,然后才能开始实际连接。 - PM 2Ring另一种方法是定义一个函数,将 nC 转换为 CCCC...C (重复 n 次),然后将其传递给 map
在来自 %
的列表 l
的每个元素上应用它,最后用 join
将它们全部连接起来,代码如下:
>>> def f(s):
x = 0
if s:
if len(s) == 1:
out = s
else:
for i in s:
if i.isdigit():
x = x*10 + int(i)
out = x*s[-1]
else:
out = ''
return out
>>> st
'%4g%10k%p'
>>> ''.join(map(f, st.split('%')))
'ggggkkkkkkkkkkp'
>>> st = '%2g%k%3p'
>>> ''.join(map(f, st.split('%')))
'ggkppp'
如果你想把所有这些内容放入一个函数定义中:
>>> def f(s):
out = ''
if s:
l = filter(None, s.split('%'))
for item in l:
x = 0
if len(item) == 1:
repl = item
else:
for c in item:
if c.isdigit():
x = x*10 + int(c)
repl = x*item[-1]
out += repl
return out
>>> st
'%2g%k%3p'
>>> f(st)
'ggkppp'
>>>
>>> st = '%4g%10k%p'
>>>
>>> f(st)
'ggggkkkkkkkkkkp'
>>> st = '%4g%101k%2p'
>>> f(st)
'ggggkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkpp'
>>> len(f(st))
107
编辑:
如果在OP不想让字符_
重复出现的情况下存在,我认为最好的方法是使用re.sub
,这样可以使事情变得更容易,做法如下:
>>> def f(s):
pat = re.compile(r'%(\d*)([a-zA-Z]+)')
out = pat.sub(lambda m:int(m.group(1))*m.group(2) if m.group(1) else m.group(2), s)
return out
>>> st = '%4g_%12k%p__%m'
>>> f(st)
'gggg_kkkkkkkkkkkkp__m'
gg_kkkkkkkkkkkkkppp
? - Iron Fistgg_kkkkkkkkkkkkkppp
,甚至当st = %2g___%12k%3p时,结果也必须是gg___kkkkkkkkkkkkkppp
。 - MLSC循环列表,检查第一个条目是否为数字,然后将第二位数字及其后面的数字添加到列表中:
string=''
l = ['2g', 'k', '3p']
for entry in l:
if len(entry) ==1:
string += (entry)
else:
number = int(entry[0])
for i in range(number):
string += (entry[1:])
string
不是一个很好的变量名,因为它是一个标准的 Python 模块的名称。此外,如果一个数字有多于 1 位数,这个答案将无法正常工作。 - PM 2Ring
%234
是什么意思?它是表示“打印两次34”,还是无效因为后面没有字母,或者其他什么意思?那么%55a5
呢?是打印五十五次a5
,还是打印五次5a5
,或者先打印五次5
然后再打印a5
?这里有很多情况你都没有具体说明。 - jpmc26