【问题标题】:Python check if list items are integers? [duplicate]Python检查列表项是否为整数? [复制]
【发布时间】:2013-05-30 06:42:36
【问题描述】:

我有一个列表,其中包含字符串格式的数字和字母。

mylist=['1','orange','2','3','4','apple']

我需要想出一个只包含数字的新列表:

mynewlist=['1','2','3','4']

如果我有办法检查列表中的每个项目是否可以转换为整数,我应该能够通过执行以下操作来提出我想要的:

for item in mylist:
    if (check item can be converted to integer):
        mynewlist.append(item)

如何检查字符串是否可以转换为整数?或者有什么更好的方法吗?

【问题讨论】:

    标签: python string list integer


    【解决方案1】:

    试试这个:

    mynewlist = [s for s in mylist if s.isdigit()]
    

    来自docs

    str.isdigit()

    如果字符串中的所有字符都是数字并且至少有一个字符,则返回true,否则返回false。

    对于 8 位字符串,此方法取决于语言环境。


    如 cmets 中所述,返回 Trueisdigit() 不一定表示可以通过 int() 函数将字符串解析为 int,返回 False 不一定表示不能.不过,上述方法应该适用于您的情况。

    【讨论】:

    • 值得注意的是,str.isdigit() 将在某些通过int() 时抛出异常的事物上返回True,而在某些不会抛出异常的事物上返回False。例如:上标数字,“+1”。
    • @Lattyware 你能举一个可能导致异常的值的例子吗?
    • "²" - 上标数字 2。它从 str.isdigit() 返回 True,但 int("²") 会抛出 ValueError。反过来,"+1" 将解析得很好,但 str.isdigit("+1") 将返回 False
    • @Lattyware 显然负整数也是如此。
    • @squiguy 当然这样的案例很多,我只是举了两个简单的例子。
    【解决方案2】:

    快速、简单,但可能并不总是正确的:

    >>> [x for x in mylist if x.isdigit()]
    ['1', '2', '3', '4']
    

    如果您需要获取数字,则更传统:

    new_list = []
    for value in mylist:
        try:
            new_list.append(int(value))
        except ValueError:
            continue
    

    注意:结果为整数。如果需要,将它们转换回字符串, 将上面的行替换为:

    try:
        new_list.append(str(int(value)))
    

    【讨论】:

    • 但是如果你想忽略数字作为字符串'123',例如,目前你包括它们
    【解决方案3】:

    您可以使用异常处理,因为 str.digit 仅适用于整数,并且也可能因以下情况而失败:

    >>> str.isdigit(' 1')
    False
    

    使用生成器函数:

    def solve(lis):                                        
        for x in lis:
            try:
                yield float(x)
            except ValueError:    
                pass
    
    >>> mylist = ['1','orange','2','3','4','apple', '1.5', '2.6']
    >>> list(solve(mylist))                                    
    [1.0, 2.0, 3.0, 4.0, 1.5, 2.6]   #returns converted values
    

    或者你可能想要这个:

    def solve(lis):
        for x in lis:
            try:
                float(x)
                return True
            except:
                return False
    ...         
    >>> mylist = ['1','orange','2','3','4','apple', '1.5', '2.6']
    >>> [x for x in mylist if solve(x)]
    ['1', '2', '3', '4', '1.5', '2.6']
    

    或使用ast.literal_eval,这将适用于所有类型的数字:

    >>> from ast import literal_eval
    >>> def solve(lis):
        for x in lis:
            try:
                literal_eval(x)
                return True
            except ValueError:   
                 return False
    ...         
    >>> mylist=['1','orange','2','3','4','apple', '1.5', '2.6', '1+0j']
    >>> [x for x in mylist if solve(x)]                               
    ['1', '2', '3', '4', '1.5', '2.6', '1+0j']
    

    【讨论】:

    • 请注意,此行为与 OP 所说的不同 - OP 将列表中的元素显示为字符串。也就是说,在大多数情况下,它可能是最好的答案。此外,float() 的使用可能很好,但如果提问者只想要整数值,int() 是合适的。
    【解决方案4】:

    检查某个东西是否可以转换为int 的常用方法是try 它并查看,遵循EAFP 原则:

    try:
        int_value = int(string_value)
    except ValueError:
        # it wasn't an int, do something appropriate
    else:
        # it was an int, do something appropriate
    

    所以,在你的情况下:

    for item in mylist:
        try:
            int_value = int(item)
        except ValueError:
            pass
        else:
            mynewlist.append(item) # or append(int_value) if you want numbers
    

    在大多数情况下,围绕一些以mynewlist.append(item) 结尾的琐碎代码的循环可以转换为列表解析、生成器表达式或对mapfilter 的调用。但在这里,您不能,因为无法将 try/except 放入表达式中。

    但是如果你把它包装在一个函数中,你可以:

    def raises(func, *args, **kw):
        try:
            func(*args, **kw)
        except:
            return True
        else:
            return False
    
    mynewlist = [item for item in mylist if not raises(int, item)]
    

    ……或者,如果您愿意:

    mynewlist = filter(partial(raises, int), item)
    

    这样使用更干净:

    def raises(exception_types, func, *args, **kw):
        try:
            func(*args, **kw)
        except exception_types:
            return True
        else:
            return False
    

    这样,您可以将您期望的异常(或异常元组)传递给它,这些异常将返回 True,但如果引发任何意外异常,它们将传播出去。所以:

    mynewlist = [item for item in mylist if not raises(ValueError, int, item)]
    

    ... 会做你想做的事,但是:

    mynewlist = [item for item in mylist if not raises(ValueError, item, int)]
    

    ... 应该会引发TypeError

    【讨论】:

      猜你喜欢
      • 2020-05-14
      • 2011-07-22
      • 2010-12-16
      • 2018-05-19
      • 2016-04-14
      • 1970-01-01
      • 2012-07-15
      • 2023-03-03
      • 2021-07-28
      相关资源
      最近更新 更多