Python __str__とリスト


107

Javaでは、List.toString()を呼び出すと、List内の各オブジェクトのtoString()メソッドが自動的に呼び出されます。たとえば、リストにオブジェクトo1、o2、o3が含まれている場合、list.toString()は次のようになります。

"[" + o1.toString() + ", " + o2.toString() + ", " + o3.toString() + "]"

Pythonで同様の動作を取得する方法はありますか?クラスに__str __()メソッドを実装しましたが、オブジェクトのリストを出力するときは、次のようにします。

print 'my list is %s'%(list)

次のようになります。

[<__main__.cell instance at 0x2a955e95f0>, <__main__.cell instance at 0x2a955e9638>, <__main__.cell instance at 0x2a955e9680>]

リスト内の要素ごとにpythonに__str__を自動的に呼び出させるにはどうすればよいですか(またはそのことについてはdict)?


回答:


133

Pythonリストで文字列を呼び出すと、__repr__内部の各要素でメソッドが呼び出されます。いくつかの項目については、__str____repr__同じです。その動作が必要な場合は、次のようにします。

def __str__(self):
    ...
def __repr__(self):
    return self.__str__()

7
で識別することは__str____repr__通常、Pythonデータモデルに同意しないため、@ daniel-lewによって提案されたリスト内包解は、よりパイソン的です。
Ioannis Filippidis 2014

2
議論なし。私はよく尋ねられた質問に回答しました。これは、Pythonの初心者が問題を考えたがる方法であることがよくありますが、それが回答するための最良の方法であるとは限りません。
David Berger 14

1
Pythonはそれ自体のデータモデルと整合性があり、すべてのプリミティブと集約に対して同じことを行う必要があります。
Terrence Brannon 2017

2
Pythonリストのデフォルトの動作は明らかに間違っていると思います。内部の個々の要素ごとにstr()リストが返さstr()れることを期待します。
SuperGeo 2018年

21

リスト内包表記を使用して、各アイテムが自動的にstr()された新しいリストを生成できます。

print([str(item) for item in mylist])

6
それともprint(map(str, mylist))-それはほんの少し短い
anula

4
マイリスト内の項目もリストであるかもしれない場合は、この1つの問題は、ある
Breandánダルトン

7

あなたができる2つの簡単なことは、map関数を使うことと理解を使うことです。

しかし、これは文字列ではなく文字列のリストを取得します。そのため、文字列も結合する必要があります。

s= ",".join( map( str, myList ) )

または

s= ",".join( [ str(element) for element in myList ] )

次に、この複合文字列オブジェクトを印刷できます。

print 'my list is %s'%( s )

4

その出力を何に使用するかに応じて、おそらく__repr__より適切かもしれません。

import unittest

class A(object):
    def __init__(self, val):
        self.val = val

    def __repr__(self):
        return repr(self.val)

class Test(unittest.TestCase):
    def testMain(self):
        l = [A('a'), A('b')]
        self.assertEqual(repr(l), "['a', 'b']")

if __name__ == '__main__':
    unittest.main()

3

これを行うためにリスト内包表記を使用することについての以前の回答に同意しますが、それがあなたのボートをフロートさせるものである場合は、それを関数の後ろに隠すことができます。

def is_list(value):
    if type(value) in (list, tuple): return True
    return False

def list_str(value):
    if not is_list(value): return str(value)
    return [list_str(v) for v in value]

面白くするために、リストに含まれているすべてのものをlist_str()に再帰的にstr()しました。


+1これは__str____repr__個別に実装する場合に便利です
vincent gravitas 2014


0

これで十分です。

リストや他のコンテナクラスを印刷する場合、含まれている要素はを使用して印刷されます。これは、内部オブジェクトの表現に使用されることを意図している__repr__ため__repr__です。help(object.__repr__)私たちが呼び出す場合:それは私たちに教えてくれます:

Help on wrapper_descriptor:

__repr__(self, /)
    Return repr(self).

そして、それを呼び出すhelp(repr)と、出力されます:

Help on built-in function repr in module builtins:

repr(obj, /)
    Return the canonical string representation of the object.

    For many object types, including most builtins, eval(repr(obj)) == obj.

if __str__がオブジェクトに実装され、__repr__not が実装されていない場合とrepr(obj)同様print(obj)に、デフォルトの出力を出力しません。

したがって、唯一の方法は__repr__、クラスに実装することです。これを行う1つの可能な方法は次のとおりです。

class C:           
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

C.__repr__=C.__str__       
ci = C()    


print(ci)       #C class str 
print(str(ci))  #C class str 
print(repr(ci)) #C class str 

-3

取得される出力は、__repr__関数がオーバーライドされないため、オブジェクトのモジュール名、クラス名、および16進数のメモリアドレスです。

__str__印刷を使用するときにオブジェクトの文字列表現に使用されます。ただし、オブジェクトのリストをstr出力していて、リストを繰り返し処理して各項目のメソッドを呼び出さないため、オブジェクトの表現が出力されます。

持っている__str__関数が呼び出されますが、このような何かをする必要があるでしょう:

'my list is %s' % [str(x) for x in myList]

__repr__関数をオーバーライドすると、以前と同じようにprintメソッドを使用できます。

class cell:
    def __init__(self, id):
        self.id = id
    def __str__(self):
        return str(self.id) # Or whatever
    def __repr__(self):
        return str(self) # function invoked when you try and print the whole list.

myList = [cell(1), cell(2), cell(3)]
'my list is %s' % myList

次にmy list is [1, 2, 3]、出力として" "を取得します。


この答えは、まったく無関係の質問に答えているようです。あなたはあなたがそれを正しい場所に置いたと確信していますか?
Blckknght

はいBlckknght私の答えを出したかったこのページには別の投稿からのこのページへのリンクがありました。そのため、ここに案内され、質問をした人が再びここに来て私の答えを見ると仮定して、ここに答えます。不便!!!
panagiwtis koligas

他の質問がこの質問の複製としてクローズされた場合、ここにある既存の回答が他の質問をすでに処理していると想定されています。そうでない場合は、理解できない解答をここに投稿するのではなく、その質問を再度開くようにフラグを立てる必要があります。これはほぼ確実に削除されます。ここで、他の8つの回答のいずれかでカバーされていないことを言う可能性がありますが、このページのコンテキストで回答を理解する必要があります。これは、あなたが回答しているこの質問だからです。また、同じ答えを2つ投稿しないでください。
Blckknght

1
ああ、私はもう一度見ますが、何らかの理由で@charliebeckwithが自分の回答を投稿するのではなく、完全に異なる投稿に編集したようです。これは通常の編集方法ではありません...
Blckknght

@blckknght答えがどれほどずれているか気づく前に編集を始めました。なぜ私が続けたのか、完全に説明できない。
charliebeckwith
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.