2016-03-25 20 views
3

Python yeniden ifadelerini kullanmaya yeni başlıyorum. İhtiyacım olanı elde ettim ama deneyimimi kaçırdığımdan çok çirkin. Amacım formunun dizelerden oluşan bir dizi dönüştürmek için geçerli:, yüzen bir diziyePython regex Dize dizisine dizi dizisi

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

böylece yukarıdaki dizi verimleri:

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

kod aşağıda o başarır ama gerçekten tekrarlayan ve Kötü tarz Bunu nasıl optimize edebilirim? (O kadar çok ufacık girişler için, büyük girişler için ilgili)

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

Bunu gerçekten CodeReview.SE'de yayınlamalısınız ... Ayrıca, eğer bu ifadeleri değiştirebilirseniz, eğer m: eğer m: eğer m: eğer m.groups (0): 'ise, birine, m ve m.grupsa (0): ' – Druzion

cevap

1

findall'u kullanarak d o bu tek regex:

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

bu benim için en anlaşılır çözüm – 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) 

baskılar

[100.0, -50.0, 0, -212.0] 

hızlı regex daha bir çok string.translate olacaktır:

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
  • Sen desende değişken ve görsel bölünmüş gruplara
  • Sen eşleşebilir şamandıra dizeleri desen koymak ve zaman eşleşen seçmek için or kullanabilirsiniz
  • onları doğrudan dönüştürebilirsiniz grup

Örnek:

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)