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


290

在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循环?

Answers:


430

您可以改用列表推导或生成器表达式:

', '.join([str(x) for x in list])  # list comprehension
', '.join(str(x) for x in list)    # generator expression

3
或生成器表达式:','.join(str(x)for list in x)
dF。

1
有什么想法会更快吗?
gozzilli

我的实验表明,列表理解可以在小列表上快60%(在三个对象的列表上运行10 ^ 6次)。但是,它们在大型列表上的性能类似(第二个实验在10 ^ 7 objects()列表上运行一次)。
gozzilli

3
为了获得30%的良好加速(超过上面的生成器表达式),可以使用所谓的可读性较低的map表达式(如下)。
K3 --- rnc 2013年

2
这个答案在客观上比map解决方案要差。
PascalVKooten

95

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

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

1
map()不会更改列表,它等效于[列表中o的str(o)]
dF。

11
+1:地图是一种好方法;“更改列表”不是准确的评论。
S.Lott

2
(另一)+1 ..地图的可读性也不低,只需要知道地图功能的作用
lapax 2015年

1
@Michael不正确。reduce是被删除的那个,因为它通常会让人们猜测,因此不是“ pythonic”。map另一方面,这不是问题。
PascalVKooten

1
(另一个)+1:来自Perl世界,这是宇宙中最常见的东西:join(“ sep”,list)-list的所有元素都转换为它们的字符串表示形式。我一直在努力寻找python解决方案。
杰森

2

另一个解决方案是重写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作为变量名,您正在重新定义list类(关键字)!最好使用另一个标识符名称。

希望您会发现我的回答有用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.