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)
Как проверить, что строка может быть преобразована в целое число? Или есть лучший способ сделать это?
Ответы
Ответ 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
, как и должно быть.