我该如何将字典中的字符串值转换为整型/浮点型数据类型?

50

我有一个字典列表如下:

list = [ { 'a':'1' , 'b':'2' , 'c':'3' }, { 'd':'4' , 'e':'5' , 'f':'6' } ]

如何将列表中每个字典内的值转换为整数/浮点数?

这样就变成了:

list = [ { 'a':1 , 'b':2 , 'c':3 }, { 'd':4 , 'e':5 , 'f':6 } ]

6
命名变量时最好不要使用内置类型的名称。希望这只是为了举例说明而这样做,但如果不是,请避免在您的代码中这样做。 - JoshAdel
请将您的代码从list = [ { 'a':1 , 'b':2 , 'c':3 }}, { 'd':4 , 'e':5 , 'f':6 } ]修正为list = [ { 'a':1 , 'b':2 , 'c':3 }, { 'd':4 , 'e':5 , 'f':6 } ] - Paolo
@Guandalino:刚刚现场编写了代码..抱歉。已编辑。 - siva
8个回答

53

我们必须爱上列表推导式

[dict([a, int(x)] for a, x in b.items()) for b in list]

(注意:对于仅适用于Python 2的代码,您可以使用"iteritems"代替"items")


1
虽然有点难以理解,但确实令人印象深刻!如何处理以下错误:ValueError: empty string for float()(浮点数)和 ValueError: invalid literal for int() with base 10: '0.6'(整数)? - siva
最终我想对列表项进行统计(最大值、最小值、平均值、标准差)。 - siva
你可以编写一个函数来替换列表推导式中的int()调用,以允许您需要的所有异常情况。 - Powertieke
可能是可以的,但我宁愿使用Perl :P - Powertieke

36
for sub in the_list:
    for key in sub:
        sub[key] = int(sub[key])

将其强制转换为整数而不是字符串。


哈哈,我只是在改变那个,但是是的,Jochen说得对,把你的字典命名为列表,让我有点困惑。 - Jim

7
如果这是你的确切格式,你可以浏览列表并修改字典。
for item in list_of_dicts:
    for key, value in item.iteritems():
        try:
            item[key] = int(value)
        except ValueError:
            item[key] = float(value)

如果您有更一般的需求,那么您需要对字典进行递归更新。检查元素是否为字典,如果是,则使用递归更新。如果可以转换为浮点数或整数,请将其转换并修改字典中的值。这方面没有内置函数,可能会很丑陋(并且不符合Python风格,因为通常需要调用isinstance)。

2

对于Python 3

    for d in list:
        d.update((k, float(v)) for k, v in d.items())

1
如果你决定采取“原地”解决方案,可以看一下这个:
>>> d = [ { 'a':'1' , 'b':'2' , 'c':'3' }, { 'd':'4' , 'e':'5' , 'f':'6' } ]
>>> [dt.update({k: int(v)}) for dt in d for k, v in dt.iteritems()]
[None, None, None, None, None, None]
>>> d
[{'a': 1, 'c': 3, 'b': 2}, {'e': 5, 'd': 4, 'f': 6}]

顺便提一下,键的顺序不会被保留,因为这是标准字典的工作方式,即没有顺序的概念。

1
为了处理可能出现的 intfloat 和空字符串值,我会使用列表推导式、字典推导式以及条件表达式的组合,如下所示:
dicts = [{'a': '1' , 'b': '' , 'c': '3.14159'},
         {'d': '4' , 'e': '5' , 'f': '6'}]

print [{k: int(v) if v and '.' not in v else float(v) if v else None
            for k, v in d.iteritems()}
               for d in dicts]

# [{'a': 1, 'c': 3.14159, 'b': None}, {'e': 5, 'd': 4, 'f': 6}]

然而,字典推导在Python 2中直到2.7版本才被添加。在早期版本中仍然可以作为单个表达式完成,但必须使用dict构造函数编写,如下所示:

# for pre-Python 2.7

print [dict([k, int(v) if v and '.' not in v else float(v) if v else None]
            for k, v in d.iteritems())
                for d in dicts]

# [{'a': 1, 'c': 3.14159, 'b': None}, {'e': 5, 'd': 4, 'f': 6}]

请注意,无论哪种方式,这都会创建一个新的列表字典,而不是直接在原始字典中进行修改(需要使用不同的方法来完成)。

如果 v='',即空项,我能否直接编辑“v”?试试看。谢谢。有用的。 - siva
关于如何处理空的 "v" 项的问题:您可以重写 if 表达式来像我在修订后的答案中所示一样处理它们。 - martineau
关于你的第二个问题,即在“... for k ...”处收到语法错误的问题,字典推导需要Python 2.7+或3.1+版本,因此使用早期版本可能会导致问题。 - martineau
回复我的上一条评论:你可以将@Powertieke答案中的int(x)替换为类似于我的条件表达式,以摆脱字典推导并得到适用于早期Python版本的结果。 - martineau

1
  newlist = []              # Make an empty list
  for i in list:            # Loop to hv a dict in list
     s = {}                 # Make an empty dict to store new dict data
     for k in i.keys():     # To get keys in the dict of the list
         s[k] = int(i[k])   # Change the values from string to int by int func
     newlist.append(s)      # To add the new dict with integer to the list

1

一种更通用的方法是使用 这个数字转换器,基于这个答案

def number(a, just_try=False):
    try:
        # First, we try to convert to integer.
        # (Note, that all integers can be interpreted 
        #  as float and hexadecimal numbers.)
        return int(a)
    except:
        # The order of the following conversions doesn't matter.
        # The integer conversion has failed because `a` 
        # contains hexadecimal digits [x,a-f] or a 
        # decimal point ['.'], but not both.
        try:
            return int(a, 16)
        except:
            try:
                return float(a)
            except:
                if just_try:
                    return a
                else:
                    raise


# The conversion:
[dict([a, number(x)] for a, x in b.items()) for b in list]

这将处理整数、浮点和十六进制格式。


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