2016-08-20 60 views
1

我有格式爲"1-3 6:10-11 7-9"的字符串,並從它們中創建數字集合,如下所示{1,2,3,6,10,11,7,8,9}Python - 從字符串創建集合

有關創建從號碼的範圍內設定,我有以下代碼:

def create_set(src): 
    lset = [] 
    if len(src) > 0: 
     pos = src.find('-') 
     if pos != -1: 
      first = int(src[:pos]) 
      last = int(src[pos+1:]) 
     else: 
      return [int(src)] # Only one number 
     for j in range (first, last+1): 
      lset.append(j) 
     return set(lset) 

但我無法弄清楚如何正確對待「:」當它出現的字符串中。有人能幫我嗎?

在此先感謝!

編輯:順便說一下,有沒有更緊湊的方式來解析這樣的字符串,也許使用正則表達式?

+0

我會忍不住用正則表達式解析它 - 我不是專家,但是這將是我會做的方式 - 因爲「語法」似乎是有規律的。 –

+0

@xnx我的想法正確 –

+1

爲什麼6有一個冒號? –

回答

1

編輯:順便說一下,在那裏,也許 使用正則表達式解析這種串的更緊湊的方式?

也許更清潔(略更有效)的方式:

import re 
import itertools 

allGroups = re.findall(r"(\d+)(?:-(\d+)|:)", s) 
expanded = [range(int(x), (int(x) if y == '' else int(y)) + 1) for x, y in allGroups] 
print {x for x in itertools.chain.from_iterable(expanded)} 

說明:

匹配的所有字符串,如 'AB' 或 '答:' 並返回一個列表(一, b)和(分別是, '')對:

allGroups = re.findall(r"(\d+)(?:-(\d+)|:)", s) 

這產生:

[('1', '3'), ('6', ''), ('10', '11'), ('7', '9')] 

使用列表理解將(x,y)的所有對擴展到範圍(x,y + 1)中的所有數字列表中,注意將(x,'')情況作爲(x, X + 1):

expanded = [range(int(x), (int(x) if y == '' else int(y)) + 1) for x, y in allGroups] 

這產生:

[[1, 2, 3], [6], [10, 11], [7, 8, 9]] 

使用itertools.chain.from_iterable()到列表清單變換成一個單一的迭代,其由一組理解迭代到最終組:

print {x for x in itertools.chain.from_iterable(expanded)} 

這將產生:

set([1, 2, 3, 6, 7, 8, 9, 10, 11]) 
+0

謝謝,FujiApple,這個解決方案還具有返回排序列表的好處。 – maurobio

5

像這樣的事情可能會爲你工作:

s = '1-3 6:10-11 7-9' 
s = s.replace(':', ' ') 
lset = set() 
fs = s.split() 
for f in fs: 
    r = f.split('-') 
    if len(r)==1: 
     # add a single number 
     lset.add(int(r[0])) 
    else: 
     # add a range of numbers (inclusive of the endpoints) 
     lset |= set(range(int(r[0]), int(r[1])+1)) 
print(lset) 
+0

謝謝,xnx!它非常完美! – maurobio

+0

這個答案很好,但可以選擇下面的替代方案,也許更簡單。 – FujiApple