我最近接受了一次采访。面试官问我在python
中迭代词典的方法。我说所有方法都使用用于语句。但他告诉我, lambda 怎么样?
我感到非常困惑,我认为lambda是一个匿名函数,但它如何迭代一个字典?一些代码如下:
new_dict = sorted(old_dict.items(), lambda x: x[1]) # sorted by value in dict
但在此代码中,lambda用作提供比较密钥的函数。你觉得这个问题怎么样?
答案 0 :(得分:7)
您不会使用lambda
进行迭代。在Python中迭代可迭代对象有以下几种方法:
for
声明(您的回答)[x for x in y]
,字典{key: value for key, value in x}
和设置{x for x in y}
(x for x in y)
map
,all
,itertools
模块)next
发生之前手动调用StopIteration
函数。注意: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,生成器表达式或内置函数,如sum
,sorted
或max
)都使用此协议, :
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>