I wrote some script, but I have to add some condition; the user puts a list and it must contain at least one of these types (tuple, int,s tr and sub-list).
Is there an elegant way to do that without 4 if?
I thought about for loop and using isinstance(i, type)
but its tricky, because it runs over and over and ask the different 'questions' about one kind of type
for i in List:
if isinstance(i,int):
if isinstance(i,str)
As you see this is not very elegant. I thought about putting new variable i,j,k
for each kind of type and maybe do 4 for loops:
for
for
for
for
Any ideas and clues are welcomed. Thanks!
You could add a helper function "has":
def has(items, t):
for item in items:
if isinstance(item, t):
return True
return False
def check(items):
return has(items, int) and has(items, str) \
and has(items, tuple) and has(items, list)
If you want to be more compact (but less readable), use "any" and "all":
def has(item, t):
return any([isinstance(items, t) for item in items])
def check(items):
return all([has(items, t) for t in (str, int, tuple, list)])
You may use builtin any
function. Quoting docs:
any(iterable)
Return
True
if any element of the iterable is true. If the iterable is empty, returnFalse
.
Sample usage:
expected_types = {int, str, tuple, list} # set of expected types
for i in seq:
if any(isinstance(i, t) for t in expected_types):
pass # do something
To check all elements of sequence you may use built-in all
function. So, to check all elements of sequence you may simply use:
expected_types = {int, str, tuple, list}
if all(any(isinstance(i, t) for t in expected_types) for i in seq):
pass # condition is sufficient
Both all()
and any()
performs short-circuiting, so operation has reasonable performance. If you don't care about subclasses you may check type - it speeds up isinstance(i, t) for t in expected_types
from O(n)
to O(1)
.
expected_types = {int, str, tuple, list}
if all(type(i) in expected_types for i in seq):
pass # condition is sufficient, but not for subclasses of int, str, tuple or list
All checks above tests if all objects are instances of one of expected_types
, but not if all types occurs in sequence. If you want to ensure "at least one of each type" condition you may use collections.Counter .
c = collections.Counter(type(o) for o in seq)
if all(c[t] >= 1 for t in {int, list, tuple, str}):
pass # seq contains at least one of each type
You can use a tuple of different types with isinstance
:
>>> isinstance('a', (str, list, tuple, int))
True
Combine with any
>>> data = [1, 'a', (2, 4, 6)]
>>> any(isinstance(x, (str, list, tuple, int)) for x in data)
True
or, if you want to do something with the objects of one these types:
for x in data:
if isinstance(x, (str, list, tuple, int)):
print('found')
To get the type of an object, you can use the built-in type() function. Passing an object as the only parameter will return the type object of that object:
eg:
a=5
type(a) will return 'int'
If you want to check for all instances if pass then use all
otherwise use any
as below.
eg
types = set(['int','str','dict'])#Used set to ensure no duplicate
l = ['s',3,{'s':3}]
for j in types:
if any(isinstance(i,eval(j)) for i in l):
print 'passed'
Output-
passed
passed
passed
使用内置的all
和any
:
all([any(lambda x: isInstance(x,i), lst_to_check) for i in instances_list])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.