81

Pythonでは、何かがシーケンスではないかどうかを判断する簡単な方法はありますか?私はただやろうとしました: if x is not sequenceしかし、Pythonはそれが好きではありませんでした

4

7 に答える 7

93

iter(x)TypeErrorifを繰り返すことはできませんが、そのチェックはセットと辞書を「受け入れ」ますが、や番号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

于 2010-05-30T00:46:43.270 に答える
8

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です。

于 2015-06-25T07:00:44.727 に答える
4

Python 2.6.5のドキュメントでは、文字列、Unicode 文字列、リスト、タプル、バッ​​ファ、および xrange のシーケンス タイプについて説明しています。

def isSequence(obj):
    return type(obj) in [str, unicode, list, tuple, buffer, xrange]
于 2010-05-30T01:03:12.767 に答える
-3

なぜ、なぜ尋ねる

長さを取得しようとし、例外が false を返す場合

def haslength(seq):
    try:
        len(seq)
    except:
        return False
    return True
于 2012-08-26T03:35:13.123 に答える
-6

なぜあなたはこれをやっている?ここでの通常の方法は、特定のタイプのもの (シーケンス、数値、またはファイルのようなオブジェクトなど) を要求し、何もチェックせずに使用することです。Python では、通常、セマンティック情報を運ぶためにクラスを使用せず、単に定義されたメソッドを使用します (これは「ダック タイピング」と呼ばれます)。また、何が期待できるかが正確にわかっている API を好みます。関数の動作を変更する場合は、キーワード引数、前処理、または別の関数の定義を使用します。

于 2010-05-30T00:58:53.580 に答える