如何将“5cm”之类的字符串转换为整数

时间:2013-06-16 16:42:01

标签: python string list

我有一个像[2,3,4,"5cm", 6,"2.5km"]这样的输入列表,我希望得到一个结果:

[2,3,4,5,6,2.5]

我想以这种方式开始

for element in inputList:

6 个答案:

答案 0 :(得分:5)

您可以使用regex

>>> import re
>>> lis = [2,3,4,"5cm", 6,"2.5km"]
>>> r = re.compile(r'\d+(.\d+)?')
>>> [float(r.search(x).group(0)) if isinstance(x,str) else x  for x in lis]
[2, 3, 4, 5.0, 6, 2.5]

使用ast.literal_eval代替float5.0作为5

>>> from ast import literal_eval
>>> [literal_eval(r.search(x).group(0)) if isinstance(x,str) else x  for x in lis]
[2, 3, 4, 5, 6, 2.5]

开始你的方式:

import re
from ast import literal_eval
ans = []
r = re.compile(r'\d+(.\d+)?')            #regex to match an integer or decimal 
inputList = [2,3,4,"5cm", 6,"2.5km"]
for element in inputList:
   if isinstance(element, str):          #if element is a string then apply the regex
       num = r.search(element).group(0)  
       ans.append(literal_eval(num))
   else:
       ans.append(element)               #else append the element as it is
print ans
#[2, 3, 4, 5, 6, 2.5]

另一种解决方案,考虑到您的输入始终是有效的:

>>> from string import digits
>>> allowed = '-+.' + digits
>>> allowed                        #allowed characters
'-+.0123456789'
>>> lis = [2,3,4,"5cm", 6,"2.5km"]
>>> ans = []
for item in lis:
    if isinstance(item, str):
    # if item is a string
        num = ''               # Initialize an empty string
        for c in item:         # Iterate over the string, one character at time.
            if c in allowed:   # If the character is present in `allowed` then
                 num += c      # concatenate it to num
            else:
                break          # else break out of loop
        ans.append(float(num)) # Append the float() output of `num` to `ans` or use 
                               # `ast.literal_eval`
    else:
        ans.append(item)
...         
>>> ans
[2, 3, 4, 5.0, 6, 2.5]

答案 1 :(得分:4)

import re

inputList = [2, 3, 5, "2", "2.5km", "3cm"]
outputList = []
for element in [str(i) for i in inputList]:
    match = re.match(r"([-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?).*", element)
    if match:
        outputList.append(float(match.group(1)))

print outputList

此解决方案使用regular expressions从字符串中提取数字部分。 re是一个非常有用的模块,您应该定义自己的模型。

因为正则表达式只适用于字符串,所以我们首先必须将那些数字的列表元素转换为字符串。我们使用list comprehension[str(i) for i in inputList]

执行此操作

如果你写print [str(i) for i in inputList],那么你会得到:

["2", "3", "5", "2", "2.5km", "3cm"]

所以这几乎和以前一样,但数字现在是字符串。 现在,使用它我们可以创建一个识别数字的正则表达式。我自己没有提出这个问题,而是来自here%f)。我们将字符串化列表中的每个元素与该模式匹配,并将结果字符串转换为我们附加到float的{​​{1}}。

请注意,在某些区域设置中,小数点(outputList)可能由不同的字符表示。如果这在您的情况下很重要,您可以按如下方式接收当前的语言环境小数点字符:

\.

我希望这个解释能让你更清楚,发生了什么 - 如果没有,请在下面发表评论。

答案 2 :(得分:1)

这是一个不使用regex的解决方案::

my_list = [2,3,4,"5cm", 6,"2.5km"]

def get_digits(s):
    return ''.join(ele for ele in s if not ele.isalpha())


def convert_to_nums(my_list):
    result = []
    for ele in my_list:
        if isinstance(ele, (int, float)):
            result.append(ele)
        else:
            ele = get_digits(ele)
            try:
                result.append(int(ele))
            except ValueError:
                result.append(float(ele))
    return result

结果:

>>> convert_to_nums(my_list)
[2, 3, 4, 5, 6, 2.5]

答案 3 :(得分:1)

首先,使用正则表达式:它是正确的工具。其次,使用最适合您已知需求的最简单解决方案:具体来说,我们可以使用正则表达式从字符串末尾删除非数字。

import re

vals = [2, 3, 4, "5cm", 6, "2.5km"]

rgx  = re.compile(r'\D+$')
nums = [float( rgx.sub('', str(v)) ) for v in vals]

print nums

如果你真的必须避开正则表达式,那么这是一种方法,无需诉诸异常处理,类型检查或任何比最简单的if-else更复杂的逻辑。

def leading_digits(v):
    for c in str(v):
        if c in '0123456789.': yield c
        else:                  return

def intfloat(s):
    f = float(s)
    i = int(f)
    return i if i == f else f

vals = [2, 3, 4, "5cm", 6, "2.5km", '8.77cm extra junk w/ digits 44']
nums = [intfloat(''.join(leading_digits(v))) for v in vals]

print nums   # [2, 3, 4, 5, 6, 2.5, 8.77]

答案 4 :(得分:0)

如果你不能忍受正则表达式,那么还有一个(可能是最不优雅的):

input = [2,3,4,"5cm", 6,"2.5km"]
result = list()
for ele in input:
    while type(ele) is str:
        ele = ele[:-1]  # Strip off one letter from the end.
        for tt in (int, float):
            try: 
                ele = tt(ele)
                break
            except:
                pass
    result.append(ele)

print result  

答案 5 :(得分:0)

这是一个受@Akavall启发并使用ast.literal_eval进行简化的解决方案:

from ast import literal_eval
def get_digits(s):
    return ''.join(ele for ele in s if not ele.isalpha())

def convert_to_nums(my_list):
    return [literal_eval(d) for d in (get_digits(s) for s in map(str, my_list))]

结果:

>>> my_list = [2,3,4,"5cm", 6,"2.5km"]
>>> convert_to_nums(my_list)
[2, 3, 4, 5, 6, 2.5]