Python正则表达式 将字符串数组 转换为浮点数数组

3

我是一个Python正则表达式的初学者。尽管我已经实现了我需要的功能,但由于缺乏经验,我的代码看起来非常丑陋。我的目标是将一个字符串数组转换为以下形式:

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): 合并成一个 if m and m.groups(0): - Kaspar Lee
4个回答

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
使用findall,您可以在单个正则表达式中完成此操作:
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
  • 您可以将模式放入变量中,并以视觉方式拆分组
  • 您可以在模式中匹配浮点字符串并直接转换它们
  • 您可以使用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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接