2
from operator import itemgetter
from itertools import takewhile

xs = [ ('foo',1), ('bar',1), ('baz',2) ]

xs12番目の項目でソートされます-の後にsはもうありません'bar'

def item_map(xs):
    getcount = itemgetter(1)
    return list(map(getcount,xs))

print(item_map(xs))
>>> [1, 1, 2]

すべてのタプルの2番目の要素のリストを返します。

def item_take(xs):   
    return list(takewhile(lambda x: x[1] == 1, xs))

print(item_take(xs))
[('foo', 1), ('bar', 1)]

==1の2番目の要素を持つタプルを返します。

def could_this_work(xs):
    match = itemgetter(1) == 1 
    return list(takewhile(match, xs))

print(could_this_work(xs))
TypeError: 'bool' object is not callable

==1である2番目の要素を持つタプルを返しません

itemgetterラムダの代わりに使用する方法はありますか?またはitemgetter、このように使用することはできませんか?

編集。takewhile理由で使用されています。私はそれが何をするのか理解しています。この関数は、ソートされたリストで使用されます。タプルがこれに対して逆方向になっていることを感謝しますが、私が使用したコードは、私が望んでいることと期待していることに対して正しいものです。

4

4 に答える 4

2

ラムダ関数は、実際には2つの関数の合成です:operator.itemgetter(1)operator.eq。純粋関数型でこれを行うには、次のような関数が必要になりcompose()ます。

def compose(f, g):
    def composed(x):
        return f(g(x))
    return composed

この関数を使用すると、次のことができます

from operator import itemgetter, eq
from functools import partial

def take_items(a):
    return takewhile(compose(partial(eq, 1), itemgetter(1)), a)

しかし、これは神の考えではないと思います。私はおそらく簡単に行くでしょう

def take_items(a):
    for x in a:
        if x[1] != 1:
            break
        yield x

これは、コードのリーダーの一部について考える必要が少ないと思います。

于 2012-06-22T12:22:48.343 に答える
2

試す:

getcount = itemgetter(1)
match = lambda x: getcount(x) == 1

あなたがしたことはを 1 と比較しitemgetter(1)ました。この比較は False を返します。次に、それを呼び出します。False(x)動作しないため、このエラーが発生します。

itemgetter(n)基本的には次のような関数です。

def itemgetter(n):
    return lambda x: x[n]

が別の関数を返すことに気付きました。それを と比較してintも意味がありません。

于 2012-06-22T12:18:33.183 に答える
1

itemgetter比較は行わず、アイテムを取得する関数を提供するだけです。比較が必要な場合は、独自の関数を作成する必要があります。

また、リスト内包表記を使用できることに注意してください。

def could_this_work(xs):
    return [x for x in xs if x[1] == 1]

またはジェネレーター式でさえ、無限のストリームでも遅延して動作する可能性があります:

def could_this_work(xs):
    return (x for x in xs if x[1] == 1)

(これらはあなたの英語が言ったことを行います:2番目の要素に1があるアイテムを取得します。1以外の要素を見つけたときに停止したい場合は、Svenの答えを使用してください。)

于 2012-06-22T12:20:28.093 に答える
0

これを実際のコードで実行しないでください。正直なところ、ラムダを使用してください。

from operator import itemgetter, eq
from functools import partial
from itertools import takewhile

def compose_unary(func1, func2):
    return lambda x: func1(func2(x))

def item_take(xs):
    return list(takewhile(compose_unary(partial(eq, 1), itemgetter(1)), xs))

takewhile実際には、あなたが考えているように見えるわけではないことに注意してください。述語に一致しない最初の要素で停止し、それ以降の要素は無視されます。

于 2012-06-22T12:27:22.687 に答える