如何使用python 3.4中的矩阵制作地图和lambdas?

时间:2015-05-23 13:12:51

标签: python dictionary lambda

我经常避免让我写这样的帖子,但我是python 3.4的新手,我需要这个代码的帮助。

假设我们有以下列表:

v = [ [ x, y ] for x in ['a','b','c'] for y in range(1,5) ]

结果列表:[['a','1'],['a','2'],...]

现在我想加入那些字符串。我尝试了以下内容:

p = map(lambda (x, y): ''.join(x,y), v)

它不起作用。

错误:

TypeError: join() takes exactly one argument (2 given)

我试图查阅文档但是我不能解决我的问题。

有人有想法吗?

5 个答案:

答案 0 :(得分:1)

你可以这样做:

>>> list(map(lambda x: ''.join(map(str, x)), v))
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']

这为lambda x: ''.join(map(str, x))中的每个元素执行函数vv中的元素是一个列表,其中包含一个字符串和一个整数作为值。这意味着x函数收到的lambda是包含这两个值的列表。

然后我们需要确保该列表中的所有值都是字符串,然后再将它们传递给join()。这意味着我们会调用map(str, x)将子列表x中的所有值转换为字符串(['a', 1]变为['a', '1'])。然后我们可以通过将结果传递给''.join(...)['a', '1']变为['a1'])来加入它们。这是针对v中的每个列表完成的,因此这为我们提供了所需的结果。

map的结果是Python 3.x中的所谓mapobject,因此我们将所有内容都包含在list()调用中,最终得到一个列表。

此外,列表理解在这里可以说更具可读性:

>>> [x[0] + str(x[1]) for x in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']

答案 1 :(得分:1)

  1. lambda (x, y): ''.join(x,y)不合法Python 3.删除了可迭代的参数解包。 如果您实际运行了在您提到的版本上显示的代码,则会出现语法错误,而不是您显示的错误。

  2. 如果你确实有一个你描述的列表,而不是你实际制作的列表,你需要给str.join一个可迭代的参数,而不是2个参数,所以lambda (x, y): ''.join([x,y])(类似于您展示的代码,但不是合法的Python 3),或者更简单地说,lambda x_y: ''.join(x_y)

  3. 但这对你不起作用,因为str.join需要一个可迭代的字符串,而你的案例中得到的列表列表是[ ['a', 1], ['a',2], ... ],而不是[ ['a', '1'], ['a','2'], ... ] 。您不能以这种方式加入字符串和数字。 (这很好,因为str.join甚至不适合这项工作。)

  4. 使用map + lambda 始终愚蠢。只需在您可能使用的所有情况下使用生成器表达式{{1 }} + map

  5. 请参阅以下示例(我使用列表推导而不是生成器表达式,因此我们将获得有用的代表):

    lambda

答案 2 :(得分:1)

如果您只有一定数量的要加入的元素,可以使用str.format

print(list(map(lambda x: "{}{}".format(*x) , v)))  

['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']

您也可以使用"{}" * len(x)

为任意数量的元素执行此操作
print(list(map(lambda x: ("{}" * len(x)).format(*x) , v)))

*x解包序列,"{}" * len(x)为每个子列表中的每个元素创建一个{}

或者在列表comp中解压缩:

print([ "{}{}".format(*x) for x in v])

答案 3 :(得分:1)

我同意迈克的观点,map(lambda很愚蠢。在这种情况下,'{}{}'.format几乎完成了你的lambda应该做的工作,所以你可以改用它:

starmap('{}{}'.format, v)

使用itertools.starmap。如果您想使用map,可以这样做:

map('{}{}'.format, *zip(*v))

但我真的只是做

(c + str(n) for c, n in v)

编辑:map + lambda与generator表达式的比较,显示后者更短,更清晰,更灵活(解包),并且更快:

>>> from timeit import timeit

>>> r = range(10000000)
>>> timeit(lambda: sum(map(lambda xy: xy[0]+xy[1], zip(r, r))), number=1)
7.221420832748007
>>> timeit(lambda: sum(x+y for x, y in zip(r, r)), number=1)
5.192609298897533

>>> timeit(lambda: sum(map(lambda x: 2*x, r)), number=1)
5.870139625224283
>>> timeit(lambda: sum(2*x for x in r), number=1)
4.4056527464802

>>> r = range(10)
>>> timeit(lambda: sum(map(lambda xy: xy[0]+xy[1], zip(r, r))), number=1000000)
7.047922363577214
>>> timeit(lambda: sum(x+y for x, y in zip(r, r)), number=1000000)
4.78059718055448

答案 4 :(得分:0)

您可以使用其他列表理解:

not animatable

如果您不需要>>> [''.join((x, str(y))) for x, y in v] ['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4'] ,您可以在第一个列表理解中执行:

v