1

このようなリストから重複を除外する必要があるという問題が発生しました。

a = [1,1,4,5,6,5]

これは私のコードです:

def unique(a):
    uni = []
    for value in a:
        if value[0] not in found:
            yield value
            found.add(value[0])
            print list(unique(a))

ただし、リストを定義してa試してみると、次のunique(a)出力が得られます。

<generator object unique at 0x0000000002891750>

誰かが私が間違っていることを教えてもらえますか?リストを取得できないのはなぜですか?

編集、新しい問題..フィルタリングされたリストを印刷することができましたが、リストの順序が失われます。どうすればこれを防ぐことができますか?

def unique(a):
        s = set()
        for i in a:
            if i not in s:
                s.add(i)
        return s
4

4 に答える 4

4

あなたは見られたすべての要素を追跡しなければなりません。最良の方法はset、ルックアップの複雑さとして使用することですO(1)

>>> def unique(it):
        s = set()
        for el in it:
            if el not in s:
                s.add(el)
                yield el


>>> list(unique(a))
[1, 4, 5, 6]

要素の順序を維持する必要がない場合は、setコンストラクターを利用して、リストに戻すことができます。これにより、すべての重複が削除されますが、要素の順序が破棄されます。

list(set(a))
于 2012-10-13T23:30:59.943 に答える
3

まず、重複を削除するには、次のセットを使用します。

>>> a = [1, 1, 4, 5, 6, 5]
>>> set(a)
{1, 4, 5, 6}
>>> list(set(a)) # if you really _need_ a list, you can convert it back
[1, 4, 5, 6]

次に、取得する出力はgenerator object unique at 0x...、戻り値として単純なリストではなく、ジェネレーターオブジェクトがあることを意味します。yieldそして、これは関数で使用した後に期待すべきことです。yieldすべての関数をジェネレーターにし、要求した場合(または反復した場合)にすべての結果のみを提供します。完全な結果を取得したいだけの場合は、オブジェクトを呼び出しlist()て、ジェネレータオブジェクトからリストを作成できますlist(unique(a))

ただし、関数によってエラーが発生することに気付くでしょうTypeError: 'int' object is not subscriptable。その理由はvalue[0]あなたが使うことです。valueはリストの要素であり(リストを反復処理します)、それ自体は整数です。整数から最初の要素を取得することはできないので、おそらくvalueそこだけを意味します。

次に、リストを最初にfound定義したにもかかわらず、に要素を追加するので、そこで名前の1つを決定する必要があります。uniまた、メソッドはappendであり、ではありませんadd

最後に、関数内で同じパラメーターを使用してメソッドを繰り返し呼び出すことは、実際には使用しないでください。これにより、スタックがいっぱいになり、何も使用されないため、出力を削除します。

次に、これで終わります。これは問題なく機能します。

>>> def unique(a):
        found = [] # better: use a set() here
        for value in a:
            if value not in found:
                yield value
                found.append(value)
>>> list(unique(a))
[1, 4, 5, 6]

しかし、それでも、これは実際には良い解決策ではありません。set代わりに使用する必要があります。これにより、セットが作成された後、そのセットを操作するためのさらなるメソッドが提供されます(たとえば、包含性のクイックチェック)。

私も入力するだけで答えを得る必要がありますunique(a)

その場合は、関数からを削除して、最後にリストをyield value返します。found

于 2012-10-13T23:36:53.633 に答える
2

これはよく知られている古典です:

>>> def unique(xs):
...     seen = set()
...     seen_add = seen.add
...     return [x for x in xs if x not in seen and not seen_add(x)]
...
>>> unique([1, 2, 3, 3, 4, 1, 3, 5, 5, 4, 6])
[1, 2, 3, 4, 5, 6]
于 2012-10-14T00:31:55.980 に答える
0

これを行う通常の方法はlist(set(a)

def unique(a):
  return list(set(a))

さて、あなたの質問に来ます。yield印刷ではなく反復する必要があるジェネレーターを返します。したがって、を含む関数がある場合は、次のyieldように繰り返します。for return_value from function_that_yields():

あなたの質問にはもっと問題があります。定義foundしていないので、コンテナではない可能性のある値にインデックスを付けます。

于 2012-10-13T23:27:25.590 に答える