Подтвердить что ты не робот

Преобразование всех нечисловых значений в 0 (ноль) в Python

Я ищу самый простой способ преобразования всех нечисловых данных (включая пробелы) в Python в нули. Принимая следующие, например:

someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]]

Я хотел бы, чтобы результат был следующим:

desiredData = [[1.0,4,7,-50],[0,0,0,12.5644]]

Итак, "7" должно быть 7, но "8 бананов" должны быть преобразованы в 0.

4b9b3361

Ответ 1

import numbers
def mapped(x):
    if isinstance(x,numbers.Number):
        return x
    for tpe in (int, float):
        try:
            return tpe(x)
        except ValueError:
            continue
    return 0
for sub  in someData:
    sub[:] = map(mapped,sub)

print(someData)
[[1.0, 4, 7, -50], [0, 0, 0, 12.5644]]

Он будет работать для разных числовых типов:

In [4]: from decimal import Decimal

In [5]: someData = [[1.0,4,'7',-50 ,"99", Decimal("1.5")],["foobar",'8 bananas','text','',12.5644]]

In [6]: for sub in someData:
   ...:         sub[:] = map(mapped,sub)
   ...:     

In [7]: someData
Out[7]: [[1.0, 4, 7, -50, 99, Decimal('1.5')], [0, 0, 0, 0, 12.5644]]

if isinstance(x,numbers.Number) улавливает подэлементы, которые уже являются float, int и т.д., если он не является числовым типом, мы сначала пытаемся выполнить листинг для int, а затем плавать, если ни один из них не является успешным, мы просто возвращаем 0.

Ответ 2

Другое решение, использующее регулярные выражения

import re

def toNumber(e):
    if type(e) != str:
        return e
    if re.match("^-?\d+?\.\d+?$", e):
        return float(e)
    if re.match("^-?\d+?$", e):
        return int(e)
    return 0

someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]]
someData = [map(toNumber, list) for list in someData]
print(someData)

вы получаете:

[[1.0, 4, 7, -50], [0, 0, 0, 12.5644]]

Примечание Это не работает для чисел в научной нотации

Ответ 3

В качестве альтернативы вы можете использовать модуль decimal в понимании вложенного списка:

>>> [[Decimal(i) if (isinstance(i,str) and i.isdigit()) or isinstance(i,(int,float)) else 0 for i in j] for j in someData]
[[Decimal('1'), Decimal('4'), Decimal('7'), Decimal('-50')], [0, 0, 0, Decimal('12.56439999999999912461134954')]]

Обратите внимание, что преимущество decimal заключается в том, что при первом условии вы можете использовать его для получения десятичного значения для цифровой строки и представления float для float и integer для int:

>>> Decimal('7')+3
Decimal('10')

Ответ 4

Целые числа, поплавки и отрицательные числа в кавычках прекрасны:

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

def is_int(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

someData = [[1.0,4, '7', - 50, '12.333 ',' -90 '], [' - 333.90 ',' 8 bananas ',' text ',' ', 12.5644]]

 for l in someData:
        for i, el in enumerate(l):
            if isinstance(el, str) and not is_number(el):

                l[i] = 0
           elif isinstance(el, str) and is_int(el):

                l[i] = int(el)
           elif isinstance(el, str) and is_number(el):

                l[i] = float(el)

print(someData)

Вывод:

[[1.0, 4, 7, -50, 12.333, -90], [-333.9, 0, 0, 0, 12.5644]]

Ответ 5

Учитывая, что вам нужны как типы данных int, так и float, вы должны попробовать следующий код:

desired_data = []
for sub_list in someData:
    desired_sublist = []
    for element in sub_list:
        try:
            some_element = eval(element)
            desired_sublist.append(some_element)
        except:
            desired_sublist.append(0)
    desired_data.append(desired_sublist) 

Это может быть не оптимальный способ сделать это, но все же он выполняет задание, которое вы просили.

Ответ 6

lists = [[1.0,4,'7',-50], ['1', 4.0, 'banana', 3, "12.6432"]]
nlists = []
for lst in lists:
    nlst = []
    for e in lst:
        # Check if number can be a float
        if '.' in str(e):
            try:
                n = float(e)
            except ValueError:
                n = 0
        else:
            try:
                n = int(e)
            except ValueError:
                n = 0

        nlst.append(n)
    nlists.append(nlst)

print(nlists)

Ответ 7

Неудивительно, что у Python есть способ проверить, есть ли что-то число:

import collections
import numbers
def num(x):
    try:
        return int(x)
    except ValueError:
        try:
            return float(x)
        except ValueError:
            return 0

def zeronize(data):
    return [zeronize(x) if isinstance(x, collections.Sequence) and not isinstance(x, basestring) else num(x) for x in data]

someData = [[1.0,4,'7',-50],['8 bananas','text','',12.5644]]
desiredData = zeronize(someData)


desiredData = `[[1, 4, 7, -50], [0, 0, 0, 12]]`

Функция определена в случае, если у вас есть вложенные списки произвольной глубины. Если вы используете Python 3.x, замените basestring на str.

Этот этот и этот вопрос может иметь значение. Кроме того, this и .

Ответ 8

Однострочный:

import re
result = [[0 if not re.match("^(\d+(\.\d*)?)$|^(\.\d+)$", str(s)) else float(str(s)) if not str(s).isdigit() else int(str(s)) for s in xs] for xs in somedata]
>>> result
[[1.0, 4, 7, 0], [0, 0, 0, 12.5644]]

Ответ 9

Я предполагаю, что пробелы, о которых вы говорите, являются пустыми строками. Поскольку вы хотите преобразовать все строки, независимо от них, содержащие символы или нет. Мы можем просто проверить, является ли тип объекта строкой. Если это так, мы можем преобразовать его в целое число 0.

cleaned_data = []
for array in someData:
    for item in array:
        cleaned_data.append(0 if type(item) == str else item)

>>>cleaned_data
[1.0, 4, 0, -50, 0, 0, 0, 12.5644]