Pythonでは、何かがシーケンスではないかどうかを判断する簡単な方法はありますか?私はただやろうとしました:
if x is not sequence
しかし、Pythonはそれが好きではありませんでした
7 に答える
iter(x)
TypeError
ifを繰り返すことはできませんが、そのチェックはセットと辞書を「受け入れ」ますが、や番号x
などの他の非シーケンスを「拒否」します。None
一方、文字列(ほとんどのアプリケーションはシーケンスではなく「単一のアイテム」と見なしたい)は実際にはシーケンスです(したがって、文字列に特化していない限り、どのテストでもシーケンスであることを確認します)。したがって、このような単純なチェックでは不十分なことがよくあります。
Python 2.6以降では、抽象基本クラスが導入され、他の強力な機能の中でも、このような「カテゴリチェック」をより優れた体系的にサポートしています。
>>> import collections
>>> isinstance([], collections.Sequence)
True
>>> isinstance((), collections.Sequence)
True
>>> isinstance(23, collections.Sequence)
False
>>> isinstance('foo', collections.Sequence)
True
>>> isinstance({}, collections.Sequence)
False
>>> isinstance(set(), collections.Sequence)
False
文字列は(シーケンスであるため)依然として「シーケンス」と見なされますが、少なくともdictとsetが邪魔にならないことに注意してください。「シーケンスである」という概念から文字列を除外する場合は、次を使用するか(ただし、文字列と同様にシーケンスであるが変更できないタプルも除外します)、明示的に実行します。collections.MutableSequence
import collections
def issequenceforme(obj):
if isinstance(obj, basestring):
return False
return isinstance(obj, collections.Sequence)
味わう季節、そして温かい料理を!-)
PS:Python 3の場合は、str
の代わりに使用basestring
し、Python 3.3以降の場合:のような抽象基本クラスSequence
はに移動しましたcollections.abc
。
Python はダック タイピングに「準拠」しているため、アプローチの 1 つは、オブジェクトにメンバー (メソッド) があるかどうかを確認することです。
シーケンスには長さがあり、アイテムのシーケンスがあり、スライス [ doc ] をサポートします。したがって、次のようになります。
def is_sequence(obj):
t = type(obj)
return hasattr(t, '__len__') and hasattr(t, '__getitem__')
# additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__')
それらはすべて特別なメソッドで__len__()
あり、アイテムの数を返す__getitem__(i)
必要があり、アイテムを返す必要があり(シーケンスではi番目のアイテムですが、マッピングではありません)、__getitem__(slice(start, stop, step))
サブシーケンスを返す必要があり、__setitem__
期待__delitem__
どおりです。これはそのような契約ですが、オブジェクトが実際にこれらを行うかどうかは、オブジェクトが契約を遵守するかどうかに依存します。
上記の関数はマッピングにも返されることに注意True
してください。たとえばdict
、マッピングにもこれらのメソッドがあるためです。これを克服するには、より重い作業を行うことができます。
def is_sequence(obj):
try:
len(obj)
obj[0:0]
return True
except TypeError:
return False
しかし、ほとんどの場合、これは必要ありません。オブジェクトがシーケンスであるかのようにやりたいことを行い、必要に応じて例外をキャッチします。これはよりpythonicです。
Python 2.6.5のドキュメントでは、文字列、Unicode 文字列、リスト、タプル、バッファ、および xrange のシーケンス タイプについて説明しています。
def isSequence(obj):
return type(obj) in [str, unicode, list, tuple, buffer, xrange]
なぜ、なぜ尋ねる
長さを取得しようとし、例外が false を返す場合
def haslength(seq):
try:
len(seq)
except:
return False
return True
なぜあなたはこれをやっている?ここでの通常の方法は、特定のタイプのもの (シーケンス、数値、またはファイルのようなオブジェクトなど) を要求し、何もチェックせずに使用することです。Python では、通常、セマンティック情報を運ぶためにクラスを使用せず、単に定義されたメソッドを使用します (これは「ダック タイピング」と呼ばれます)。また、何が期待できるかが正確にわかっている API を好みます。関数の動作を変更する場合は、キーワード引数、前処理、または別の関数の定義を使用します。