我有一个列表,我需要转换为浮动。由于我没有输入数据,因此有些元素会有意外的额外期间,例如39.04.1450
。我需要能够自动删除所有句点,除了显示的第一个句点,以便在我说list=float(list)
时我不会收到错误。
示例清单:
latitude= [' -86.57', ' 39.04.1450', ' 37.819' ,' 45.82', ' 54.42', ' 0.' ,' 53.330444',
' +45.75' ,' 52.36', ' 43.2167', ' -36.75', ' 6.8N' ,' 40.833' ,' -97.981',
' 41.720', ' 41.720', ' 37.41' ,' 37.41' ,' 37.41', ' 37.41']
如您所见,latitude[1]
有一个额外的小数点。当然,我还需要在6.8N
中删除N,但这是一个单独的问题。
答案 0 :(得分:4)
我会这样做:
def fix_float(s):
return s.replace('.', '[DOT]', 1).replace('.', '').replace('[DOT]', '.')
该函数将'.'
的第一次出现替换为'[DOT]'
。然后,它删除'.'
的所有发生。最后,它将'[DOT]'
替换为'.'
。
要将其应用于列表的所有元素,请写下:
fixed_latitudes = [fix_float(s) for s in latitude]
答案 1 :(得分:2)
def my_float(s):
s=s.split(".")
return float(".".join([s[0],"".join(s[1:]))])
会分开。并且只重新加入第一个句号...但它不会对-6.8N
答案 2 :(得分:2)
您可以使用regular expressions:
import re
pattern = re.compile(r'(\d+\.\d+)\.')
new_lst = [re.sub(pattern, r'\1', i).replace('N', '') for i in latitude]
\d
表示任何数字,+
表示一个或多个,\.
与点字符匹配。括号正在捕获匹配的那部分,稍后在sub()
中使用\1
(意味着第一个捕获组)。
答案 3 :(得分:1)
如果您的损坏数据最后只包含N
且多个.
,那么这是一个小问题...除此之外,您还需要添加更多内容
latitude = [' -86.57', ' 39.04.1450', ' 37.819', ' 45.82', ' 54.42', ' 0.', ' 53.330444', ' +45.75', ' 52.36', ' 43.2167', ' -36.75', ' 6.8N', ' 40.833', ' -97.981', ' 41.720', ' 41.720', ' 37.41', ' 37.41', ' 37.41', ' 37.41']
flist = []
for i in latitude:
try:
flist.append(float(i))
except ValueError:
if (i[-1] == 'N'):
flist.append(float(i[:-1]))
else:
flist.append(float("{}.{}".format(i.split(".")[0],''.join(i.split(".")[1:]))))
print (flist)
输出
[-86.57, 39.04145, 37.819, 45.82, 54.42, 0.0, 53.330444, 45.75, 52.36, 43.2167, -36.75, 6.8, 40.833, -97.981, 41.72, 41.72, 37.41, 37.41, 37.41, 37.41]
答案 4 :(得分:1)
您可以使用正则表达式从列表中提取数字并立即将它们转换为浮点数。
import re
lat = lambda l: float(re.search('[+-]*\d*\.\d*',l).group(0))
print map(lat,latitude)
编辑:
对不起,我没有注意到,小数点后第二位的数字也是有效的。
一个新的解决方案仍然期望第一个点是可以的,其余的都将被删除。
其中一个值包含N,所以我想可能还有S表示它的南部,即负纬度。因此,我将此假设实现为代码。
def valid_lat(s):
a = re.findall('\s*[+-]*\d*\.\d*',s)[0]
b = s.lstrip(a)
d = b.replace('.','')
c = re.sub('[nNsS]$','',d)
sign = 1.
if re.match('[sS]$',d):sign = -1.
return (float(a + c))*sign
然后只是map
它:
map(valid_lat,latitude)
答案 5 :(得分:0)
这个怎么样?
def lol_float(_str):
# check where decimal point is (starting from right) '3.45' -> 2
dpi = (len(_str) - _str.count('.') - _str.index('.')) if '.' in _str else 0
# '3.45' -> 345.0
float_as_int = float(filter(lambda x: x.isdigit(), _str))
# dpi = 2, float_as_int = 34.0 -> 3.45
return float_as_int / (10 ** dpi)
输出:
>>> lol_float('3.34')
3.34
>>> lol_float('3.45')
3.45
>>> lol_float('345')
345.0
>>> lol_float('34.5')
34.5
>>> lol_float('3.4.5')
3.45
>>> lol_float('3.45')
3.45
>>> lol_float('345')
345.0
>>> lol_float('3.4..5')
3.45
>>> lol_float('3.4..5.4')
3.454
只是原创......:)
答案 6 :(得分:0)
您可以使用str.rstrip
删除任何字母:
from string import ascii_letters
out = []
for x in latitude:
x = x.rstrip(ascii_letters)
spl = x.split(".")
if len(spl) > 2:
out.append(float("{}.{}".format(spl[0],"".join(spl[1:]))))
else:
out.append(float(x)))
print(out)
[-86.57, 39041450.0, 37.819, 45.82, 54.42, 0.0, 53.330444, 45.75, 52.36, 43.2167, -36.75, 6.8, 40.833, -97.981, 41.72, 41.72, 37.41, 37.41, 37.41, 37.41]
您可以在单个列表组件中执行此操作,但效率较低:
print([float(x[::-1].rstrip(ascii_letters).replace(".","")[::-1]) if x.count(".") > 1 else float(x.rstrip(ascii_letters)) for x in latitude ])