python中的lambda可以迭代dict吗?

时间:2015-10-12 09:09:30

标签: python dictionary lambda

我最近接受了一次采访。面试官问我在python中迭代词典的方法。我说所有方法都使用用于语句。但他告诉我, lambda 怎么样?

我感到非常困惑,我认为lambda是一个匿名函数,但它如何迭代一个字典?一些代码如下:

new_dict = sorted(old_dict.items(), lambda x: x[1]) # sorted by value in dict

但在此代码中,lambda用作提供比较密钥的函数。你觉得这个问题怎么样?

6 个答案:

答案 0 :(得分:7)

您不会使用lambda进行迭代。在Python中迭代可迭代对象有以下几种方法:

  1. for声明(您的回答)
  2. 理解,包括列表[x for x in y],字典{key: value for key, value in x}和设置{x for x in y}
  3. 生成器表达式:(x for x in y)
  4. 传递给将迭代它的函数(mapallitertools模块)
  5. next发生之前手动调用StopIteration函数。
  6. 注意:3除非您稍后迭代该生成器,否则不会迭代它。如果是4,则取决于功能。

    对于迭代特定集合(如dict或list),可以使用更多技术,如while col: remove element或使用索引切片技巧。

    现在lambda出现了。您可以在其中一些函数中使用lambdas,例如:map(lambda x: x*2, [1, 2, 3])。但是这里的lambda与迭代过程本身无关,你可以传递一个常规函数map(func, [1, 2, 3])

答案 1 :(得分:3)

你可以像这样使用lambda迭代dict:

d = {'a': 1, 'b': 2}
values = map(lambda key: d[key], d.keys())

答案 2 :(得分:1)

使用普通lambda迭代Python中的任何内容都听起来非常错误。当然迭代序列和集合的最Pythonic方法是使用列表推导和生成器表达式,如@Andrey呈现。

如果面试官倾向于理论/计算机科学的更多答案,那么值得注意的是,使用lambdas来迭代是非常可能的,尽管我必须强调这不是Pythonic也不是有用的学术练习以外的语境:

# the legendary Y combinator makes it possible
# to let nameless functions recurse using an indirection
Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
# our iterator lambda
it = lambda f: lambda Lst: (Lst[0], f(Lst[1:])) if Lst else None
# see it in action:
Y(it)([1,2,3])
=> (1, (2, (3, None)))

答案 3 :(得分:1)

使用lambda的字典迭代

dct = {1: '1', 2 : '2'}

使用lambda遍历字典:

map(lambda x : str(x[0]) + x[1], dct.iteritems())

这里x [0]是关键 x [1]是值

结果: ['11','22']

使用lambda过滤字典:

filter(lambda x : x[0] > 1, dct.iteritems())

结果: [(2,'2')]

答案 4 :(得分:0)

在python中迭代dict的最好方法是:

dic ={}

iter_dic = dic.iteritems().next
iter_dic()
...
iter_dic()

但你可以用lambda func构建它:

iter_dic = lambda dic: dic.keys()[0],dic.pop(dic.keys()[0])
iter_dic(dic)
...
iter_dic(dic)

答案 5 :(得分:0)

lambda本身不会迭代任何东西。正如你所想的那样,它只是定义了一个匿名函数 - 除了只能够有一个表达式的句法规则之外,lambda只会做一个使用def的类似函数。 lambda中的代码可能会迭代某些东西,但只能以与其他函数可能使用的方式相同的方式(假设它们是表达式,并且在lambda内有效)。

在你提到的使用sorted的例子中,关键函数在被排序的列表的每个元素上调用 - 但是sorted本身就是这样做,并且迭代完成。当您提供关键功能时,sorted会执行与此类似的操作:

def sorted(seq, key):
    decorated = [(key(elem), i) for i, elem in enumerate(seq)]
    # Sort using the normal tuple lexicographic comparisons
    decorated.sort()
    return [seq[i] for _,i in decorated]

如您所见,sorted在此处进行迭代,而不是lambda。实际上,没有理由为什么键具有是一个lambda - 任何函数(或任何可调用的)都会对sorted产生影响。

在最低级别,只有一种方法可以在Python中迭代dict(或者实际上是任何其他可迭代的),即使用迭代器协议。这就是for循环在幕后的作用,你也可以使用这样的while语句:

it = iter(my_iterable)
while True:
    try:
        val = next(it)
    except StopIteration:
        # Run else clause of for loop
        break
    else:
        # Run for loop body

这里的注释并不是迭代器协议的严格组成部分,它们是for循环的一部分(但至少有一个循环体主要是首先迭代的点)

使用迭代的其他函数和语法(例如list,set和dict comprehensions,生成器表达式或内置函数,如sumsortedmax)都使用此协议, :

  • 使用Python for循环,
  • 执行类似上述while循环的操作(特别是对于用C编写的模块),
  • 委托使用其中一个
  • 的另一个函数或语法

可以通过以下两种方式之一创建一个类,使其实例可以迭代:

  • 直接提供迭代器协议。您需要一个名为__iter__的方法(由iter调用),它返回迭代器。该迭代器有一个名为__next__的方法(在Python 2中仅为next),由next调用,并在迭代器的当前位置返回值并使其前进(或引发{{1}如果它已经在最后);或
  • 实现序列协议的一部分(这意味着表现得像列表或元组)。对于前向迭代,只需StopIteration__getitem__,直到my_sequence[0](其中my_sequence[1]为数字,才能定义my_sequence[n-1]就足够了序列中的项目)和更高的索引引发错误。您通常还要定义n,这是__len__时使用的。{/ li>