在python 3.4中,如何使映射和lambda与矩阵一起工作?

在python 3.4中,如何使映射和lambda与矩阵一起工作?,python,dictionary,lambda,Python,Dictionary,Lambda,我经常避免写这样的文章,但我是Python3.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

我经常避免写这样的文章,但我是Python3.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:.joinmapstr,x。v中的元素是一个列表,其中一个字符串和一个整数作为值。这意味着lambda函数接收到的x是包含这两个值的列表

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

map的结果是Python3.x中所谓的mapobject,因此我们将所有内容包装在一个列表调用中,以列表结束

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

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

>>> list(map(lambda x: ''.join(map(str, x)), v))
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
这将为v中的每个元素执行函数lambda x:.joinmapstr,x。v中的元素是一个列表,其中一个字符串和一个整数作为值。这意味着lambda函数接收到的x是包含这两个值的列表

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

map的结果是Python3.x中所谓的mapobject,因此我们将所有内容包装在一个列表调用中,以列表结束

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

>>> [x[0] + str(x[1]) for x in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
lambda x,y:.joinx,y不是合法的Python 3。删除了可拆卸的参数解包。如果您实际运行了在您提到的版本上显示的代码,您将得到一个语法错误,而不是您显示的错误

如果您确实有一个如您所描述的列表,而不是您实际创建的列表,那么您需要为str.join提供一个iterable参数,而不是两个参数,因此lambda x,y:.join[x,y],它类似于您展示的代码,但不是合法的Python 3,或者更简单地说,lambda x_y:.joinx_y

但是,这对您不起作用,因为str.join接受一个字符串的iterable,并且在您的案例中,列表的结果列表是[[a',1],[a',2],…],而不是[[a',1'],['a','2'],…]。不能用这种方式连接字符串和数字。这很好,因为str.join甚至不是适合该作业的工具

使用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']
lambda x,y:.joinx,y不是合法的Python 3。删除了可拆卸的参数解包。如果您实际运行了在您提到的版本上显示的代码,您将得到一个语法错误,而不是您显示的错误

如果您确实有一个如您所描述的列表,而不是您实际创建的列表,那么您需要为str.join提供一个iterable参数,而不是两个参数,因此lambda x,y:.join[x,y],它类似于您展示的代码,但不是合法的Python 3,或者更简单地说,lambda x_y:.joinx_y

但是,这对您不起作用,因为str.join接受一个字符串的iterable,并且在您的案例中,列表的结果列表是[[a',1],[a',2],…],而不是[[a',1'],['a','2'],…]。不能用这种方式连接字符串和数字。这很好,因为str.join甚至不是适合该作业的工具

使用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']

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

您还可以使用{}*lenx对任意数量的元素执行此操作:

*x解压序列,{}*lenx为每个子列表中的每个元素创建一个{}

或在列表comp中解包:

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

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

您还可以使用{}*lenx对任意数量的元素执行此操作:

*x解压序列,{}*lenx为每个子列表中的每个元素创建一个{}

或在列表comp中解包:

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

您可以使用另一个列表:

>>> [''.join((x, str(y))) for x, y in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
>>> [''.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']
如果您不需要v,您可以在第一个列表中执行以下操作:

>>> [''.join((x, str(y))) for x, y in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
>>> [''.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']

您可以使用另一个列表:

>>> [''.join((x, str(y))) for x, y in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
>>> [''.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']
如果你不需要v,你可以 在第一个列表中可以做到:

>>> [''.join((x, str(y))) for x, y in v]
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']
>>> [''.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']
我同意迈克的看法,maplambda很傻。在本例中,{}{}。格式几乎完成了lambda应该完成的工作,因此您可以使用它:

starmap('{}{}'.format, v)
那就用。如果要使用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
我同意迈克的看法,maplambda很傻。在本例中,{}{}。格式几乎完成了lambda应该完成的工作,因此您可以使用它:

starmap('{}{}'.format, v)
那就用。如果要使用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

你有例外吗?怎么没用?没用-什么没用?语法错误?很抱歉,我修复了它str.join:S.joinetrable->strlambda x,y:.joinx,y的签名无效。你确定那是你正在使用的版本吗?你有例外吗?怎么没用?没用-什么没用?语法错误?很抱歉,我修复了它str.join:S.joinetrable->strlambda x,y:.joinx,y的签名无效。你确定你使用的是这个版本吗?它有效。但我不明白你的第一个解决方案。@Guillermeduarte:我会扩展我的答案。它有效。但我不明白你的第一个解决方案。@Guillermeduarte:我会扩展我的答案。对不起,我不明白为什么使用maplamba是愚蠢的。“我来自R,在那里写这样的行是很常见的。”Guillermeduarte如Mike所说:只需使用生成器表达式即可。请看编辑:我刚才添加的答案的一部分。对不起,我不明白为什么使用maplamba是愚蠢的。“我来自R,在那里写这样的行是很常见的。”Guillermeduarte如Mike所说:只需使用生成器表达式即可。请参阅我刚才添加的“编辑:我答案的一部分”。