Python中的string.join(list)应用在对象数组而不是字符串数组上

330

在 Python 中,我可以这样做:

>>> list = ['a', 'b', 'c']
>>> ', '.join(list)
'a, b, c'

当我有一个对象列表时,是否有一种简单的方法来执行相同的操作?

>>> class Obj:
...     def __str__(self):
...         return 'name'
...
>>> list = [Obj(), Obj(), Obj()]
>>> ', '.join(list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, instance found

还是说我必须使用 for 循环?

4个回答

487
你可以使用列表推导式或生成器表达式代替:
', '.join([str(x) for x in list])  # list comprehension
', '.join(str(x) for x in list)    # generator expression

3
可以使用生成器表达式来将列表中的元素转换成字符串并拼接起来,具体方法是:', '.join(str(x) for x in list)。 - dF.
1
你有任何想法哪个会更快? - gozzilli
我的实验表明,在小列表上,列表推导式可以快60%(在一个由三个object()组成的列表上运行了10^6次实验)。然而,在大列表上它们的性能相似(第二次实验在一个由10^7个object()组成的列表上运行了一次)。 - gozzilli
3
为了使速度提升30%(比上面的生成器表达式),可以使用据称较难阅读的 map 表达式(如下)。 - K3---rnc
2
这个答案比“map”解决方案客观上更差。 - PascalVKooten
不应使用str,而应该使用.encode('utf-8')。 - Andrew

106

内置的字符串构造函数会自动调用obj.__str__:

''.join(map(str,list))

1
map()不会改变列表,它相当于[str(o) for o in list]。 - dF.
12
+1:地图是一个不错的方法;“更改列表”不是一个准确的评论。 - S.Lott
3
另一个+1的映射函数并不难读,只需要知道这个映射函数的作用即可。 - lapax
1
@Michael 不正确。reduce 是被移除的一个,因为它通常让人猜测,因此不符合“Pythonic”的风格。另一方面,map 并没有问题。 - PascalVKooten
1
(另一个)+1:来自Perl世界,这是宇宙中最常见的事情:join("sep", list) - 列表中的所有元素都会转换为它们的字符串表示形式。我一直在努力寻找Python中的解决方案。 - jester66
显示剩余3条评论

3

我知道这是一个非常老的帖子,但我认为被忽略的是覆盖 __repr__,使得 __repr__ = __str__,这是该标记为重复的问题的接受答案。


1
另一种解决方案是覆盖str类的join运算符。
让我们定义一个新的类my_string,如下所示。
class my_string(str):
    def join(self, l):
        l_tmp = [str(x) for x in l]
        return super(my_string, self).join(l_tmp)

然后你可以这样做。
class Obj:
    def __str__(self):
        return 'name'

list = [Obj(), Obj(), Obj()]
comma = my_string(',')

print comma.join(list)

而你获得

name,name,name

顺便提一下,使用list作为变量名会重新定义列表类(关键字)!最好使用其他标识符名称。

希望你能发现我的答案有用。


永远不要这样做,为内置类型定义自己的类会使你的代码难以集成。 - Grigory

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接