2
from operator import itemgetter
from itertools import takewhile

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

xs在第二个项目上排序 - 之后没有更多1的 s 'bar'

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

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

返回每个元组的第二个元素的列表。

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

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

返回具有 == 1 的第二个元素的元组。

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 的第二个元素的元组

有没有办法itemgetter代替 lambda?或者itemgetter不能这样使用?

编辑。takewhile被使用是有原因的。我明白它的作用。此函数将用于排序列表。我很欣赏元组是倒退的,但是我使用它的代码对于我想要的和期望的都是正确的。

4

4 回答 4

2

尝试:

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

你所做的itemgetter(1)与 1 相比。这个比较返回 False。那你就这么叫。False(x)不会工作,所以你有这个错误。

itemgetter(n)基本上是一个类似于:

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

您注意到返回另一个函数,将其与 anint进行比较是没有意义的。

于 2012-06-22T12:18:33.183 回答
2

您的 lambda 函数实际上是两个函数的组合: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 回答
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)

(这些按照您的英语所说:获取第二个元素中带有 1 的项目。如果您想在找到非 1 元素时停止,请使用 Sven 的答案。)

于 2012-06-22T12:20:28.093 回答
0

请不要在实际代码中执行此操作。老实说,只需使用 lambda。

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 回答