首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何优雅地将列表中的“1-3,6-8”转换为“1 2 3 6-7 8”?

如何优雅地将列表中的“1-3,6-8”转换为“1 2 3 6-7 8”?
EN

Stack Overflow用户
提问于 2016-11-05 16:58:45
回答 6查看 160关注 0票数 2

问题

背景:

我有一个包含10,000个列表的列表,其中包含需要转换为特定格式的不规则数据。这些数据在转换后将被摄入到熊猫的数据中。

TL/DR;如何优雅地转换列表中以下正则表达式的匹配字符串?

Regex‘d{1,3}-\d{1,3},d{1,3}-\d{1,3}’

示例: '1-3,6-8‘到'1 2 3 6 7’

当前解决方案:使用列表理解的需要多个类型的转换来转换字符串,并且不适合作为持久的解决方案。

代码语言:javascript
复制
pat = re.compile('\d{1,3}-\d{1,3},\d{1,3}-\d{1,3}')

row = ['sss-www,ddd-eee', '1-3,6-8', 'XXXX', '0-2,3-7','234','1,5']

lst = [((str(list(range(int(x.split(',')[0].split('-')[0]), 
    int(x.split(','[0].split('-')[1])+1))).strip('[]').replace(',', '')+' '
    +str(list(range(int(x.split(',')[1].split('-')[0]), 
    int(x.split(',')[1].split('-')[1]) + 1))).strip('[]').replace(',', ''))) 
    if pat.match(str(x)) else x for x in row]

结果

代码语言:javascript
复制
    ['sss-www,ddd-eee', '1 2 3 6 7 8', 'XXXX', '0 1 2 3 4 5 6 7', '234', '1,5']
EN

回答 6

Stack Overflow用户

发布于 2016-11-05 17:08:40

抓捕小组就更容易了。

然后将组列表转换为整数,并在一个与itertools.chain链接的列表理解中对它们进行2乘2的处理。

代码语言:javascript
复制
import re,itertools

pat = re.compile('(\d{1,3})-(\d{1,3}),(\d{1,3})-(\d{1,3})')

z='1-3,6-8'

groups = [int(x) for x in pat.match(z).groups()]

print(list(itertools.chain(*(list(range(groups[i],groups[i+1]+1)) for i in range(0,len(groups),2)))))

结果:

代码语言:javascript
复制
[1, 2, 3, 6, 7, 8]

不过,你不确定那是“优雅”。它仍然很复杂,主要是因为大多数对象返回需要显式转换为list的生成器。

票数 1
EN

Stack Overflow用户

发布于 2016-11-05 17:15:41

有几种方法可以做到这一点,以下是我的方法:

代码语言:javascript
复制
import re

txt =  '1-3,6-8'

# Safer to use a raw string
pat  = re.compile(r'(\d{1,3})-(\d{1,3}),(\d{1,3})-(\d{1,3})')
m = pat.match(txt)
if m:
    start1, end1, start2, end2 = m.groups()
    result  = [i for i in range(int(start1), int(end1)+1)]
    result += [i for i in range(int(start2), int(end2)+1)]
    print(result)

给予:

代码语言:javascript
复制
[1, 2, 3, 6, 7, 8]

我在这里假设Python 3(如问题中所述)。

Python 2可以使用:

代码语言:javascript
复制
result  = range(int(start1), int(end1)+1)   
result += range(int(start2), int(end2)+1)
票数 1
EN

Stack Overflow用户

发布于 2016-11-05 17:26:06

我想你也想处理更长的序列,比如1-10,15,23-25?您实际上不需要正则表达式,常规字符串处理函数将很好地工作。

代码语言:javascript
复制
def parse_sequence(seq):
    result = []
    for part in seq.split(','):
        points = [int(s) for s in part.split('-')]
        if len(points) == 2:
            result.extend(range(points[0], points[1]+1))
        elif len(points) == 1:
            result.append(points[0])
        else:
            raise ValueError('invalid sequence')
    return result
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40440873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档