文字列配列ではなくオブジェクト配列のPython string.join(list)


291

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ループに頼らなければなりませんか?

回答:


432

代わりに、リスト内包表記またはジェネレータ式を使用できます。

', '.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%速くなる可能性があります(3つのオブジェクトのリストで10 ^ 6回実験を実行します)。ただし、それらのパフォーマンスは大きなリストでも同様です(2番目の実験は10 ^ 7個のobject()リストで1回実行されます)。
gozzilli

3
30%高速化するには(上記のジェネレーター式より)、読みにくいと思われるmap式(下記)を使用できます。
K3 --- rnc 2013

2
この答えは、mapソリューションよりも客観的に悪いです。
PascalVKooten 2015年

96

組み込みの文字列コンストラクタは自動的に次を呼び出しますobj.__str__

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

1
map()はリストを変更せず、[リスト内のoのstr(o)]
dF

11
+1:地図は良いアプローチです。「リストの変更」は正確なコメントではありません。
S.Lott、2009年

2
(別の)+1 ..マップは読みにくくはありません。マップ関数の機能を知る必要があるだけです
lapax

1
@Michael不正解です。reduceそれは通常、人々が推測することを残し、したがって「pythonic」ではなかったため、削除されたものでした。map一方、問題はありません。
PascalVKooten 2015年

1
(別の)+1:これは、Perlの世界からのものです。これは、ユニバースで最も一般的なものです。join( "sep"、list)-そして、listのすべての要素は、文字列表現に変換されます。私はpythonで解決策を見つけるのに本当に苦労しています。
ジェイソン

2

別の解決策は、strクラスの結合演算子をオーバーライドすることです。

新しいクラス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

ところで、リストを変数名として使用することで、リストクラス(キーワード)を再定義しています!できれば、別の識別子名を使用してください。

私の答えがお役に立てば幸いです。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.