从元组生成一个字符串

时间:2016-11-15 17:01:56

标签: python python-3.x

我正在寻找一种好的,有效的和pythonic的方式来做这样的事情:

('zone1', 'pcomp110007')

到此:

'ZONE 1, PCOMP 110007'

如果可能的话,不使用regex(除非确实产生了很大的不同......)。因此,将每个字母转换为大写,在字母和数字之间加一个空格,并用逗号连接。

我写的内容如下:

tags = ('zone1', 'pcomp110007')


def sep(astr):
    chars = ''.join([x.upper() for x in astr if x.isalpha()])
    nums = ''.join([x for x in astr if x.isnumeric()])
    return chars + ' ' + nums

print(', '.join(map(sep, tags)))

哪个产生了预期的结果,但看起来有点太多了。

元组的长度可能不同,但数字总是在每个字符串的末尾。

7 个答案:

答案 0 :(得分:6)

Regex确实有帮助。这应该始终有效:

import re
tags = ('zone1', 'pcomp110007')

def sep(s):
    word = re.split(r'\d', s)[0]
    return word.upper() + " " + s[len(word):]

print(', '.join(map(sep, tags)))

答案 1 :(得分:4)

我的想法:

保持sep正常功能,就像原始代码中的可读性/维护一样,但也可以根据Abdou的回答中的建议使用re

import re
tags = ('zone1', 'pcomp110007')

def sep(astr):
    alpha, num = re.match('([^\d]+)([\d]+)', astr).groups()
    return '{} {}'.format(alpha.upper(), num) 

print(', '.join(map(sep, tags)))

编辑:请注意,如果您愿意,我认为回归也是合理的:

return alpha.upper() + ' ' + num

或旧式字符串格式:

return '%s %s' %(alpha.upper(), num)

无论你最满意的是什么。

答案 2 :(得分:3)

使用re

import re

tupl = ('zone1', 'pcomp110007')

", ".join(map(lambda x: " ".join(re.findall('([A-Z]+)([0-9])+',x.upper())[0]), tupl))

#'ZONE 1, PCOMP 7'

答案 3 :(得分:2)

我认为你的方式足够pythonic。如果你想让它“更具功能性”,那么你可以使用这个:

sep = lambda s: " ".join((filter(str.isalpha, s).upper(), filter(str.isdigit, s)))
print(', '.join(map(sep, tags)))

更新:它是Python3版本,对于Python2,您需要upper使用s,而不是filter

答案 4 :(得分:1)

这是我的刺:

>>> for i, s in enumerate(tags[1][::-1]):
...   if s.isalpha():
...     print (tags[1][:i], tags[1][i:])
        break
... 
pcomp1 10007

我走回字符串找到第一个字母,然后拆分并打印每一面(字母,数字)。我省略了转换为大写,很容易添加

答案 5 :(得分:1)

递归解决方案:

def non_regex_split(s,i=0):
    if len(s) == i:
        return s
    try:
        return '%s %d' %(s[:i], int(s[i:]))
    except:
        return non_regex_split(s,i+1)

', '.join(non_regex_split(s).upper() for s in tags)

答案 6 :(得分:1)

谢谢大家的答案。我在这里定时了几个结果和时间脚本:

setup = '''
import re
tags = ('zone1', 'pcomp110007')


def sepListComp(astr):
    res = ''.join([x.upper() for x in astr if x.isalpha()]), ''.join([x for x in astr if x.isnumeric()])
    return '{} {}'.format(*res)


def sepFilter(astr):
    res = ''.join(filter(str.isalpha, astr.upper())), ''.join(filter(str.isdigit, astr.upper()))
    return '{} {}'.format(*res)


def sepRe1(astr):
    alpha, num = re.match('([^\d]+)([\d]+)', astr).groups()
    return '{} {}'.format(alpha.upper(), num)


def sepRe2(s):
    word = re.split(r'\d', s)[0]
    return word.upper() + " " + s[len(word):]


def Recursive(s,i=0):
    if len(s) == i:
        return s
    try:
        return '%s %d' %(s[:i], int(s[i:]))
    except:
        return Recursive(s,i+1)
'''
from timeit import timeit

print('sepListComp:', timeit(stmt='", ".join(map(sepListComp, tags))', setup=setup, number=100000))
print('sepFilter:', timeit(stmt='", ".join(map(sepFilter, tags))', setup=setup, number=100000))
print('sepRe1:', timeit(stmt='", ".join(map(sepRe1, tags))', setup=setup, number=100000))
print('sepRe2:', timeit(stmt='", ".join(map(sepRe2, tags))', setup=setup, number=100000))
print('sepRecursive:', timeit(stmt='", ".join(Recursive(s).upper() for s in tags)', setup=setup, number=100000))
  • sepListComp :1.0487s
  • sepFilter :1.1690s
  • sepRe1 :0.8751s
  • sepRe2 :0.8332s
  • sepRecursive :3.4539s

所以regex获胜。结果虽然有所不同。对时间的任何意见或建议都非常感谢。