2016-03-25 17 views
3

私は初心者からPythonの正規表現です。私は必要なものを達成しましたが、経験が不足しているので本当に醜いです。上記配列の収量ように、浮動小数点数の配列にPython regex配列を浮動小数点配列に変換する

notes = ["10.0% higher", "5.0% lower", "Same as", "21.2% lower"] 

:私の目標は、フォームの文字列の配列を変換することで、以下の

changes = [10.0,-5.0,0,-21.2] 

コードはそれを達成するが、実際の繰り返しで、悪いスタイル。どうすればそれを最適化できますか? (そんなにない小さめの入力に対して、大きな入力に関連する)

changes = [] 
for note in notes: 
    m = re.search(r"(?:(\d+\.\d+\%\shigher)|(\d+\.\d+\%\slower)|(Same\sas))", note) 
    if m: 
     if m.groups(0): 
      if m.groups(0)[0]: 
       changes += [float(re.match(r"(\d+\.\d+)", m.groups(0)[0]).groups(0)[0])] 
      elif m.groups(0)[1]: 
       changes += [-float(re.match(r"(\d+\.\d+)", m.groups(0)[1]).groups(0)[0])] 
      else: 
       changes += [0.0] 
print changes 
+1

CodeReview.SEに実際に投稿する必要があります。また、if if m:if m.groups(0): 'を1つの' if m and m.groups (0): ' – Druzion

答えて

1

findallを使用するとO単一の正規表現では、この:あなたは、変数と視覚的に分割グループ

  • にパターンを置くことができる

    notes = ["10.0% higher", "5.0% lower", "Same as", "21.2% lower"] 
    
    changes = [] 
    for note in notes: 
        m = re.findall("(?:(\d+\.\d+)%)?(higher|lower|Same as)", note) 
        if len(m): 
         if m[0][1] == 'higher': 
          changes += [float(m[0][0])] 
         elif m[0][1] == 'lower': 
          changes += [-float(m[0][0])] 
         else: 
          changes += [0.0] 
    
    print changes 
    
  • +1

    これは私にとって最も分かりやすい解決策です – niklas

    1
    import re 
    
    def get_val(s): 
        if "higher" in s: 
         return float(re.sub("\D", "", s)) 
        if "lower" in s: 
         return -float(re.sub("\D", "", s)) 
        return 0 
    
    notes = ["10.0% higher", "5.0% lower", "Same as", "21.2% lower"]  
    changes = [get_val(s) for s in notes] 
    print(changes) 
    

    プリント

    [100.0, -50.0, 0, -212.0] 
    

    速く正規表現よりも多くはstring.translate次のようになります。

    import string 
    
    all_chars = string.maketrans('', '') 
    no_digits = all_chars.translate(all_chars, string.digits) 
    
    def get_val(s): 
        if "higher" in s: 
         return float(s.translate(all_chars, no_digits)) 
        if "lower" in s: 
         return -float(s.translate(all_chars, no_digits)) 
        return 0 
    
    notes = ["10.0% higher", "5.0% lower", "Same as", "21.2% lower"] 
    changes = [get_val(s) for s in notes] 
    print(changes) 
    
    1
    • あなたはパターンでフロート文字列にマッチし、直接
    • あなたはマッチを選択するために、orを使用することができ、それらを変換することができますグループ

    例:

    import re 
    
    
    notes = ["10.0% higher", "5.0% lower", "Same as", "21.2% lower"] 
    
    pattern = '(?:' \ 
        '((\d+\.\d+)\%\shigher)|' \ 
        '((\d+\.\d+)\%\slower)|' \ 
        '(Same\sas)' \ 
    ')' 
    
    changes = [] 
    
    for note in notes: 
        gr = re.search(pattern, note).groups() 
        num = float(gr[1] or gr[3] or 0) * (-1 if gr[3] else 1) 
        changes.append(num) 
    
    print(changes) # [10.0, -5.0, 0.0, -21.2] 
    
    0
    #! python3 
    
    notes = ["10.0% higher", "5.0% lower", "Same as", "21.2% lower"] 
    
    def adjustments(notes): 
        for n in notes: 
         direction = -1.0 if n.endswith('lower') else 1.0 
         offset = 0.0 if n.lower() == 'same as' else float(n.split('%')[0]) 
         yield offset * direction 
    
    changes = [x for x in adjustments(notes)] 
    print(changes) 
    
    関連する問題