2016-09-07 3 views
0

ドットのドット間の範囲を拡大する:Pythonの - 私のようなIDのリストがあるとし(id1..id2)

ids= 1/1/n1..1/1/n5 , 1/1/x1 , 1/1/g1 

予想される出力:

1/1/n1 , 1/1/n2 , 1/1/n3 , 1/1/n4 , 1/1/n5 ,1/1/x1, 1/1/g1 

をi「はidを見つけどこ意味します。 .ids、私は非常に基本的なコードを書かれている

ギャップを埋めるだろうが、私はより多くのニシキヘビ解決策を探しています

import re 
ports_list=['1/1/n1..1/1/n8'] 

n = 2 
port_range=[] 
for port in ports_list: 
    if '..' in port: 
     groups = port.split('..')  #gives ['1/1/n1', '1/1/n8'] 
     for item in groups: 
      port_split = item.split('/') 
      port_join='/'.join(port_split[:n]), '/'.join(port_split[n:]) 
      port_join=port_join[0]+"/" 
      port_split=port_split[2] # n1  n8 
      get_str=port_split[0][0] 
      num=re.findall(r'\d+', port_split) # 1 8 
      port_range.append(num[0]) 
     #remove port with '.. 
     ports_list.remove(port) 

n1=port_range[0] 
n2=port_range[1] 
final_number_list=list(range(int(n1),int(n2)+1)) 
my_new_list = [ get_str + str(n) for n in final_number_list] 
final_list=[ port_join + str(n) for n in my_new_list] 
ports_list=ports_list+final_list 
print ports_list 

予想される出力を提供します:

['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/n6', '1/1/n7', '1/1/n8'] 

しかし、どのように、それは複雑なロジックを使用せず、簡単に解決することができますか?

答えて

2

わからない、それはより読みやすいか、あなたの現在のアプローチよりも良いですが、私たちは、文字列から共通部分と範囲の境界線を抽出するために正規表現を使用することができます。

import re 


def expand(l): 
    result = [] 
    pattern = re.compile(r"^(.*?)(\d+)$") 
    for item in l: 
     # determine if it is a "range" item or not 
     is_range = '..' in item 
     if not is_range: 
      result.append(item) 
      continue 

     # get the borders and the common reusable part 
     borders = [pattern.match(border).groups() for border in item.split('..')] 
     (common_part, start), (_, end) = borders 

     for x in range(int(start), int(end) + 1): 
      result.append("%s%d" % (common_part, x)) 

    return result 

print(expand(['1/1/n1..1/1/n8'])) 
print(expand(['1/1/n1..1/1/n5', '1/1/x1', '1/1/g1'])) 

プリント:

['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/n6', '1/1/n7', '1/1/n8'] 
['1/1/n1', '1/1/n2', '1/1/n3', '1/1/n4', '1/1/n5', '1/1/x1', '1/1/g1'] 

  • ^請うと一致する:^(.*?)(\d+)$には

    文字列のイニング(私たちは.match()を使用しているため、実際に私たちのケースでは必要ありません - それはとにかく文字列の先頭から検索を開始します - ちょうど「明示的、暗黙よりも優れている」ので、そこにそれを残して)

  • (.*?)はそのキャプチャグループであります任意の文字がnon-greedy fashion
  • (\d+)で任意の回数は、1つまたは複数の連続した数字に
  • $を救うキャプチャグループは、文字列の末尾にマッチしている
0

ここにベースコードがあります。私はあなたがすでに持っているリスト内包を含めて、あなたが望むようにそれを再結合させるでしょう。すでに行っているように範囲を分割するだけです。最後の行は、適切な応答を実証するだけであり

ports_list=['1/1/n1..1/1/n8'] 

for port in ports_list: 
    if ".." in port: 
     left, right = port.split("..") 
     for i in range(int(left[-1]), int(right[-1])+1): 
      new_port = left[:-1] + str(i) 
      print new_port 

:代わりに文字列全体をデ構築、ちょうどその最後の桁を取り、範囲を実行します。

+1

いかが '1月1日/ N11保存されます。 .1/1/n15'? – alecxe

+0

それはうまくいった。 ** n18..n22 **のような「キャリー」がある場合は機能しませんが、問題の説明には記載されていません。 – Prune

関連する問題