0

给定一个嵌套字典列表,我如何使用 locale 模块将货币语言环境添加到所有整数值中。我当前的解决方案有效,但是我不知道如何使它与嵌套字典一起使用,也不觉得它像 Python 一样。

示例输入


[
   {
      'name':'Tom',
      'total_salary': 70000,
      'salary': {
         'base':  65000,
         'bonus': 5000
      }
   },
   {
      'name':'Andrew',
      'total_salary': 50000,
      'salary': {
         'base':  45000,
         'bonus': 5000
       }
   }
]

想要的输出


[
   {
      'name':'Tom',
      'total_salary': '$70000',
      'salary': {
         'base':  '$65000',
         'bonus': '$5000'
      }
   },
   {
      'name':'Andrew',
      'total_salary': '$50000',
      'salary': {
         'base':  '$45000',
         'bonus': '$5000'
      }
   }
]

当前解决方案

import locale
locale.setlocale( locale.LC_ALL, 'en_CA.UTF-8' )

def add_currency_locale(_list):
    new_list = []
    for d in _list:
        for k,v in list(d.items()):
            try:
                v = float(v)
                new_value = locale.currency(v, grouping=True)
                d[k] = new_value
            except:
                pass
        new_list.append(d)
    return new_list
4

3 回答 3

1

因为你有 line locale.setlocale( locale.LC_ALL, 'en_CA.UTF-8' ),我认为你不想拥有当地货币符号,但希望它始终是'$'。如果是这样,这是我的解决方案,否则您可以轻松替换我设置的行new_value。当您有嵌套列表或字典时,我使用递归来正确处理案例(您提供的代码似乎不适用于这些案例,但根据示例输入和输出,您需要这个。如果不这样做,请删除带有实例检查的部分并except ValueError:except (ValueError, TypeError):) 替换该行。注意我在评论中留下的笔记

# Note: variable names with one leading underscore are "private" according to python code style.
# Use trailing underscore instead
def add_currency_locale(list_):
    new_list = []
    for d in list_:
        # Note: no need to convert `d.items()` to list: you can iterate over the original
        # object, and the conversion takes time
        for k, v in d.items():
            if isinstance(v, dict):
                # Because `add_currency_locale` only works with arrays, make an array of one
                # dictionary and then only use the first (and only) element of the returned list
                d[k] = add_currency_locale([v])[0]
            elif isinstance(v, list):
                d[k] = add_currency_locale(v)
            elif isinstance(v, (int, float)):
                d[k] = f'${v}'
            else:
                d[k] = v

        new_list.append(d)

    return new_list
于 2021-04-09T17:07:33.683 回答
0

如果要使用该locale模块:

lst = [
    {
        'name':'Tom',
        'total_salary': 70000,
        'salary': {
            'base':  65000,
            'bonus': 5000
        }
    }, 
    {
        'name':'Andrew',
        'total_salary': 50000,
        'salary': {
            'base':  45000,
            'bonus': 5000
        }
    }
]

import locale
locale.setlocale( locale.LC_ALL, 'en_CA.UTF-8' )

def cnvrt(dct):
    for k, v in dct.items():
        if isinstance(v, dict):
            dct[k] = cnvrt(v)
        elif isinstance(v, int) or isinstance(v, float):
            dct[k] = locale.currency(v, grouping=True)
    return dct
print([cnvrt(i) for i in lst])

但是,这不会给你预期的输出,它只是$值的前缀。

为此,您可以使用。

def cnvrt(dct):
    for k, v in dct.items():
        if isinstance(v, dict):
            dct[k] = cnvrt(v)
        elif isinstance(v, int) or isinstance(v, float):
            dct[k] = f'${v}'
    return dct
print([cnvrt(i) for i in lst])

这通过递归调用cnvrt如果值是嵌套的dict,否则,如果它是一个intfloat它预先设置一个$。由于它是根据dict对象的期望运行的,因此您可以很好地list理解它。

最后,如果你真的想要,你可以list用你的函数处理 s 但 IMO 在这一点上做的太多了。

def cnvrt(obj):
    if isinstance(obj, list):
        obj = [cnvrt(i) for i in obj]
    elif isinstance(obj, dict):
        for k, v in obj.items():
            if isinstance(v, dict) or isinstance(v, list):
                obj[k] = cnvrt(v)
            elif isinstance(v, int) or isinstance(v, float):
                obj[k] = f'${v}'
    return obj
print(cnvrt(lst))

虽然它也适用于 inner lists 和dicts ,但有很多事情使它难以理解。

于 2021-04-09T17:07:45.507 回答
0

您可以使用此代码遍历所有数据元素并获取$分配给每个值的符号。

def add_curr(dict_list):
    new_lst = []
    for dic in dict_list:
        for k1, v1 in dic.items():
            if not isinstance(v1, dict):
                if isinstance(v1, (int, float)):
                    dic[k1] = '${}'.format(v1)
                else:
                    dic[k1] = v1
            else:    
                for k2,v2 in v1.items():
                    isinstance(v2, (int, float)):
                        dic[k1][k2] = '${}'.format(v2)
                    else:
                        dic[k1][k2] = v2
        new_lst.append(dic)

    return new_lst

add_curr(mylist)

您可以决定将转换部分用作单独的函数,并每次使用键和值调用它

if isinstance(v1, (int, float)):
    dic[k1] = '${}'.format(v1)
else:
    dic[k1] = v1

这将为您提供以下字典:

[{'name': 'Tom', 
  'total_salary': '$70000', 
  'salary': 
          {'base': '$65000', 
           'bonus': '$5000'}}, 
 {'name': 'Andrew', 
  'total_salary': '$50000', 
  'salary': 
          {'base': '$45000', 
           'bonus': '$5000'}}]
于 2021-04-09T17:16:58.720 回答