繁体   English   中英

如何在python 3.4中使Maps和lambdas与矩阵一起工作?

[英]How do I make Maps and lambdas work with a matrix in python 3.4?

我经常避免写这样的文章,但是我是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)

我试图在文档中查找,但是我不能解决我的问题。

有人有主意吗?

你可以做:

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

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

然后,在将它们传递到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. lambda (x, y): ''.join(x,y)是不合法的Python3。删除了可迭代的参数拆包。 如果您实际运行的是您提到的版本上显示的代码,则将得到语法错误,而不是显示的错误。

  2. 如果确实有一个描述的列表,而不是实际创建的列表,则需要给str.join一个可迭代的参数,而不是两个参数,因此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 总是很愚蠢。 只要在所有情况下都使用生成器表达式,就可以使用map + lambda

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

py> v = [ [ x, y ] for x in ['a','b','c'] for y in range(1,5) ]
py> [''.join([let, num]) for let, num in v]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
TypeError: sequence item 1: expected str instance, int found
py> ['{}{}'.format(let, num) for let, num in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']

如果您仅需要连接一定数量的元素,则可以使用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)为每个子列表中的每个元素创建一个{}

或解压缩列表组件:

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

我同意Mike的观点, 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

您可以使用另一个列表理解:

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

如果不需要v ,则可以在第一个列表理解中执行:

>>> [''.join((x, str(y))) for x in ['a','b','c'] for y in range(1,5)]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM