List comprehension replacing items that are not float or int

只谈情不闲聊 提交于 2019-12-19 11:48:13

问题


I have a 2 item list.

Sample inputs:

['19(1,B7)', '20(1,B8)']
['16 Hyp', '16 Hyp']
['< 3.2', '38.3302615548213']
['18.6086945477694', '121.561539536844']

I need to look for anything that isn's a float or an int and remove it. So what I need the above list to look like is:

['19(1,B7)', '20(1,B8)']
['16 Hyp', '16 Hyp']
['3.2', '38.3302615548213']
['18.6086945477694', '121.561539536844']

I wrote some code to find '> ' and split the first item but I am not sure how to have my 'new item' take the place of the old:

Here is my current code:

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

for i in range(0,len(result_rows)):
    out_row = []
    for j in range(0,len(result_rows[i])-1):
        values = result_rows[i][j].split('+')
            for items in values:
                if '> ' in items:
                newItem=items.split()
                for numberOnly in newItem:
                   if is_number(numberOnly):
                      values.append(numberOnly)

The output of this (print(values)) is

['< 3.2', '38.3302615548213', '3.2']

回答1:


This looks more like a true list comprehension way to do what you want...

def isfloat(string):
    try:
        float(string)
        return True
    except:
        return False

[float(item) for s in mylist for item in s.split() if isfloat(item)]
#[10000.0, 5398.38770002321]

Or remove the float() to get the items as strings. You can use this list comprehension only if '>' or '<' are found in the string.




回答2:


What about

def stip_chars(lst):
    for item in lst:
        yield item.strip("> ")

new_values = [v for v in strip_chars(values) if is_number(v)]

?




回答3:


If you want to edit the list in place rather than create a new list, you can iterate over it using enumerate:

for (list_index, item) in enumerate(values):
    if '> ' in item:
        values[list_index] = ' '.join(item_part for item_part in item.split() if is_number(item_part))

Or however you want to construct your new value - I'm not sure what you want if you have '5 6' in your original list.

If you want a new list, you can do something similar with a list comprehension.




回答4:


values = ['> 10000', '5398.38770002321']
print [filter(lambda s: s in '0123456789.', v) for v in values]

RETURNS:

['10000', '5398.38770002321']

List of strings, as requested.

And to make it a function:

def parse_number(value):
    return [filter(lambda s: s in '0123456789.', v) for v in values]

print parse_number(values)

As an added bonus, making this accept negative numbers would be as easy as adding a hyphen to the whitelisted string '0123456789.-'




回答5:


Iterators work well here:

def numbers_only(l):
    for item in l:
        if '> ' in item:
            item = item.split()[1]
        try:
            yield float(item)
        except ValueError:
            pass
>>> values = ['> 10000', '5398.38770002321']
>>> list(numbers_only(values))
[10000.0, 5398.38770002321]

Normally, it's easier to create a new list than it is to iterate and modify the old list



来源:https://stackoverflow.com/questions/16573306/list-comprehension-replacing-items-that-are-not-float-or-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!