我经常避免让我写这样的帖子,但我是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)
我试图查阅文档但是我不能解决我的问题。
有人有想法吗?
答案 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))
中的每个元素执行函数v
。 v
中的元素是一个列表,其中包含一个字符串和一个整数作为值。这意味着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)
lambda (x, y): ''.join(x,y)
不合法Python 3.删除了可迭代的参数解包。 如果您实际运行了在您提到的版本上显示的代码,则会出现语法错误,而不是您显示的错误。
如果你确实有一个你描述的列表,而不是你实际制作的列表,你需要给str.join
一个可迭代的参数,而不是2个参数,所以lambda (x, y): ''.join([x,y])
(类似于您展示的代码,但不是合法的Python 3),或者更简单地说,lambda x_y: ''.join(x_y)
但这对你不起作用,因为str.join
需要一个可迭代的字符串,而你的案例中得到的列表列表是[ ['a', 1], ['a',2], ... ]
,而不是[ ['a', '1'], ['a','2'], ... ]
。您不能以这种方式加入字符串和数字。 (这很好,因为str.join
甚至不适合这项工作。)
使用map
+ lambda
始终愚蠢。只需在您可能使用的所有情况下使用生成器表达式{{1 }} + map
请参阅以下示例(我使用列表推导而不是生成器表达式,因此我们将获得有用的代表):
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