2

関数を定義せずに次のことを行いたい:

if isinstance(x,(list,tuple)) and every_element_isinstance(x,basestring):
   foobar

すなわち:implementing type checking

これの省略形/はありbuiltinますか?

4

4 に答える 4

9

これが最善の解決策だと思います(質問を理解していれば)

if isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x):
    #do whatever
于 2013-01-06T11:54:31.407 に答える
5
if isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x]):
    foobar

驚くべきことに、短いリストでも長いリストでも、 を使用したリストの理解[ ... ]は、使用しない場合よりも高速です。

短いリスト:

>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c']")
2.7594685942680144
>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c']")
2.8013695153947538
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c']")
2.4351678506033068
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c']")
2.4491469896721583

長いリスト:

>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c'] * 1000", number=1000)
1.3357901657891489
>>> timeit('isinstance(x, (list, tuple)) and all(isinstance(i, basestring) for i in x)', "x=['a','b','c'] * 1000", number=1000)
1.3305278872818462
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c'] * 1000", number=1000)
1.2626525921055531
>>> timeit('isinstance(x, (list, tuple)) and all([isinstance(i, basestring) for i in x])', "x=['a','b','c'] * 1000", number=1000)
1.2881240045551863
于 2013-01-06T11:54:15.883 に答える
5

ジェネリック型を定義するビルトインはありません。しかし、この機能を模倣できる多くの検証ライブラリがあります。

https://github.com/alecthomas/voluptuousを使用した例:

>>> from voluptuous import Schema
>>> s_list = Schema([basestring]) # only strings in a list are allowed
>>> s_list("hello") 
...
voluptuous.InvalidList: expected a list
>>> s_list([123])
...
voluptuous.InvalidList: invalid list value @ data[0]
>>> s_list(["correct"])
["correct"] # returns the object, if validation was successful

数日前、タプルのサポートがこのライブラリに追加されました。

>>> s_tuple = voluptuous.Schema((basestring, ))

2 つを組み合わせて結果を取得します。

>>> from voluptuous import any

# - this is now equivalent to your code
# - raises Exceptions on invalid input
>>> schema = Schema(any(s_list, s_tuple))

double- よりもわずかに高速ですisinstance

>>> from timeit import timeit

>>> timeit('(schema(i) for i in x)', "x=['a','b','c']")
0.679318904876709

>>> timeit("""
        (isinstance(x, (list, tuple)) 
         and all(isinstance(i, basestring)) for i in x)""", "x=['a','b','c']")
0.7801780700683594
于 2013-01-06T11:54:41.957 に答える
0

官能的な「0.8.7」を使用すると、ミクからの回答を更新して「タプル部分」をスキップできます。

>>> from voluptuous import Schema
>>> from timeit import timeit
>>> s_list = Schema([basestring]) # only strings in a list are allowed
>>> timeit('(s_list(i) for i in x)', "x=['a','b','c']")
0.503572940826416
>>> timeit("(isinstance(x, (list, tuple)) and all(isinstance(i, basestring)) for i in x)", "x=['a','b','c']")
0.5400209426879883
于 2015-11-16T16:57:16.423 に答える