【问题标题】:Converting string values to float and removing strings from list将字符串值转换为浮点数并从列表中删除字符串
【发布时间】:2016-04-13 09:03:37
【问题描述】:

我有一个看起来像这样的列表

lst = ['a','b','43.23','c','9','22']

我想删除不能表示为浮点数的元素,因此我正在执行以下操作(尝试 1):

for i,j in enumerate(lst):
    try:
        lst[i]=float(j)
    except:
        lst.remove(j)

列表看起来像这样

lst = ['b', 43.23, '9', 22.0]

而我需要的是这个

lst = [43.23, 9.0 , 22.0]

所以我正在做以下事情:

for i,j in enumerate(lst):
    try:
        lst[i]=float(j)
    except:
        pass
lst = [i for i in lst if type(i) != str]

有更清洁的方法吗?

编辑:根据以下建议将示例列表的名称从“list”更改为“lst”。

【问题讨论】:

    标签: python list


    【解决方案1】:

    您可以从此stackoverflow post使用以下功能:

    def isfloat(value):
      try:
        float(value)
        return True
      except ValueError:
        return False
    

    然后,在列表推导中使用它:

    >>> l = ['a','b','43.23','c','9','22']
    >>> [float(x) for x in l if isfloat(x)]
    # [43.23, 9.0, 22.0]
    

    【讨论】:

    • 和我做的差不多。想知道我在第一次尝试时做错了什么。?
    • 在第一次尝试中,您正在从列表中删除项目,同时更改列表中的 ith 值,这就是存在差异的原因。
    • 是的,enumerate() 的 next() 迭代器中的元组值获取更新的“j”值,而索引“i”保持不变并从更新的列表中读取“j”。有什么想法可以让它发挥作用吗?
    • 当我有更好的更清洁的方法时,我不会选择重复使用列表中的索引。
    【解决方案2】:

    首先你不应该将你的变量命名为list,它会影响内置的list函数/类。您可以使用一个简单的函数来执行此操作:

    >>> lst = ['a','b','43.23','c','9','22']
    >>> def is_float(el):
    ...     try:
    ...         return float(el)
    ...     except ValueError:
    ...         pass
    ... 
    >>> [i for i in lst if is_float(i)]
    ['43.23', '9', '22']
    >>> [float(i) for i in lst if is_float(i)] # to return a list of floating point number
    [43.23, 9.0, 22.0]
    

    您的代码的问题是您试图在迭代时修改您的list。相反,您可以复制您的列表,然后使用元素索引来删除它们的值。

    lst = ['a','b','43.23','c','9','22']
    lst_copy = lst.copy()
    for el in lst:
        try:
            float(val)
        except ValueError:
            lst_copy.remove(el)
    

    当然,这比使用带有谓词的列表推导式的解决方案效率低,因为您首先需要制作原始列表的副本。

    【讨论】:

    • 和我做的差不多(当然没用过函数)。想知道我在第一次尝试时做错了什么。?
    • @AshutoshSharma 我已经更新了我的答案。我希望它现在有意义。
    【解决方案3】:

    你不应该操纵你正在迭代的列表(你也不应该把它叫做list,因为你会隐藏内置的list),因为这会弄乱索引。

    'b' 出现在您的输出中的原因是在第一次迭代期间,'a' 不是浮点数,因此它被删除了。因此,您的列表变为:

    ['b','43.23','c','9','22']
    

    并且b 变为list[0]。但是,下一次迭代调用list[1] 跳过因此'b'

    为避免此类问题,您可以定义第二个列表并将合适的值附加到该列表中:

    l1 = ['a','b','43.23','c','9','22']
    l2 = []
    
    for item in l1:
        try:
            l2.append(float(item))
        except ValueError:  # bare exception statements are bad practice too!
            pass
    

    【讨论】:

    • 知道了,但是我有一本字典,里面有很多类似上面的列表,并创建了另一本充满列表的字典..可能看起来不太好..?不过,我可以处理原始列表。
    • 更新了答案,以便解释为什么在循环遍历 @AshutoshSharma 时不应操纵列表 对于字典,您可以将 l2 分配给旧键
    【解决方案4】:

    最好考虑使用迭代器来有效地使用系统内存。这是我对解决方案的看法。

    def func(x):
        try:
            return float(x)
       except ValueError:
            pass
    
    filter(lambda x: x, map(func, li))
    

    【讨论】:

      【解决方案5】:

      借用这篇文章的想法:python: restarting a loop,第一次尝试可以用一个简单的while循环来解决

      lst = ['a','b','43.23','c','9','22']
      temp = 0
      while temp<len(lst):
            try:
               lst[temp] = float(lst[temp])
               temp+=1
            except ValueError:
               lst.remove(lst[temp])
               temp = 0
      

      这让我得到了想要的结果(通过重置循环迭代器)

      lst = [43.23, 9.0 , 22.0]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-10
        • 2011-11-25
        • 1970-01-01
        • 1970-01-01
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多