[英]Elegant way to check if a list contains int, str, tuple and sub-list
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).
用户放置一个列表,并且该列表必须至少包含以下类型之一(元组,int,s tr和子列表)。
Is there an elegant way to do that without 4 if? 如果没有4,是否有一种优雅的方法来做到这一点?
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循环并使用
isinstance(i, 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: 我考虑过为每种类型放置新的变量
i,j,k
,也许对循环做4:
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": 如果要紧凑(但可读性较差),请使用“ any”和“ 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. 您可以使用内置的
any
函数。 Quoting docs: 引用文档:
any(iterable)
任何(迭代器)
Return
True
if any element of the iterable is true.如果iterable的任何元素为
True
则返回True
。 If the iterable is empty, returnFalse
.如果iterable为空,则返回
False
。
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. 要检查序列的所有元素,可以使用内置的
all
函数。 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. all()
和any()
执行短路,因此操作具有合理的性能。 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)
. 如果您不关心子类,则可以检查类型-它可以将
isinstance(i, t) for t in expected_types
从O(n)
加快到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. 上述测试的所有检查,如果所有的对象都是一个实例
expected_types
,但如果在顺序发生的所有类型。 If you want to ensure "at least one of each type" condition you may use collections.Counter . 如果要确保“每种类型中至少有一种”条件,可以使用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
使用不同类型的元组:
>>> isinstance('a', (str, list, tuple, int))
True
Combine with any
与
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')
If you want to check for all instances if pass then use all
otherwise use any
as below. 如果要检查所有实例是否通过,则使用
all
实例,否则使用以下any
实例。
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])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.