Python проверяет, являются ли элементы списка номерами - программирование
Подтвердить что ты не робот

Python проверяет, являются ли элементы списка номерами

У меня есть список, который содержит числа и буквы в строковом формате.

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

Мне нужно создать новый список, который содержит только числа:

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

Если у меня есть способ проверить, может ли каждый элемент в списке быть преобразован в Integer, я должен уметь делать то, что хочу, делая что-то вроде этого:

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

Как проверить, что строка может быть преобразована в целое число? Или есть лучший способ сделать это?

4b9b3361

Ответ 1

Попробуйте следующее:

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

Из docs:

str.isdigit()

Возвращает true, если все символы в строке являются цифрами и есть хотя бы один символ, иначе false.

Для 8-битных строк этот метод зависит от локали.


Как отмечено в комментариях, isdigit() return True необязательно указывает, что строка может быть проанализирована как int через функцию int(), и она возвращает False не обязательно указывает, что она не может быть, Тем не менее, вышеприведенный подход должен работать в вашем случае.

Ответ 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)))

Ответ 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']

Ответ 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), можно превратить в понимание списка, выражение генератора или вызов map или filter. Но здесь вы не можете, потому что нет возможности поместить в выражение 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)]

... поднимет a TypeError, как и должно быть.