金钱(金额)格式化,每三位加上逗号分隔,Python + PHP 写法
这是我给公司的 Python 招聘准备的一道笔试题,之前看过 PHP 版本的答案,觉得很巧妙,这里把几种解法列出来。
考虑了小数的处理。
1. 字符串分片
1.1. 先算出片段数,再分片、拼接
def money_format(money):
money_parts = money.split('.')
integer_part = money_parts[0]
integer_part_length = len(integer_part)
n = (integer_part_length - 1) // 3 + 1
parts = [integer_part[(i - n) * 3:integer_part_length - (n - i) * 3 + 3] for i in range(n)]
money_parts[0] = ','.join(parts)
return '.'.join(money_parts)
- 用
split()
方法分离整数和小数部分,最后再join()
到一起; - 利用取整运算
//
求片段数,先减一再加一; - 分片时
start
索引取负值可避免分片不足三个的处理;stop
取正值好取到最后一个字符。
1.2. 先反转再分片、拼接,再反转回来
def money_format(money):
money_parts = money.split('.')
integer_part = money_parts[0][::-1]
split_parts = [integer_part[i:i + 3] for i in range(0, len(integer_part), 3)]
money_parts[0] = ','.join(split_parts)[::-1]
return '.'.join(money_parts)
- 也有利用正则进行分片的:
split_parts = filter(None, re.split(r'(.{1,3})', integer_part))
- [::-1] 表示从最后位到第零位往后一位,每次向后移动一位(分片(slice)第
stop
位不包含在结果),效果相当于反转。
附上分片的索引正负值对照:
正(包括0) | 负 |
---|---|
/ | -(len(str)+1) |
0 | -len(str) |
1 | -(len(str)-1) |
... | ... |
len(str)-2 | -2 |
len(str)-1 | -1 |
len(str) | / |
2. 字符串按字符循环
def money_format(money):
money_parts = money.split('.')
count = 0
res = ''
for i in range(len(money_parts[0])-1, -1, -1):
count += 1
if count == 4:
count = 1
res = ',' + res
res = money_parts[0][i] + res
money_parts[0] = res
return '.'.join(money_parts)
- 倒序循环,也就是个位开始,注意
range(start, stop, step)
方法的使用; - 在循环到逗号后面一位的数字时再加上逗号,免得出现
,100,000
这样的问题
3. PHP 解法
PHP 自带 money_format() 方法,需要 strfmon,时区相关。
不用自带的方法,用字符串处理的函数:
<?php
function money_comma($money){
$money_parts = explode('.', $money);
$money_parts[0]=strrev(implode(',', str_split(strrev($money_parts[0]), 3)));
return implode('.', $money_parts);
}
?>
概览
比较简单的题目,基础不牢地动山摇啊。