web-dev-qa-db-ja.com

リストの要素に関数を適用する方法は?

リスト内のすべての要素に関数を適用したいのですが、結果を表示するのではなく、実際に要素(オブジェクト)を変更したいと思います。これはmap()またはリスト内包表記の使用に関する問題だと思います。

class Thing(object):
    pass

# some collection of things
my_things

# they are all big...

# produces SyntaxError: invalid syntax
[i.size = "big" for i in my_things]

# produces SyntaxError: lambda cannot contain assignment
map(lambda i: i.size="big", [i for i in my_things]) 

# no error, but is it the preferred way?
for i in my_things:
    i.size="big"

これを行う方法は何ですか?

12
cammil

そして何が悪いのか

for i in my_things:
    i.size = "big"

mapもリストの内包も実際には新しいリストを作成しないので、使用しないでください。そして、あなたはそのオーバーヘッドを必要としませんね?

15
freakish

私は何も問題がないことに同意しますが

for i in my_things:
    i.size = "big"

python one-liners。;)に熱中している人もいます。

1つのオプションは、クラスにsetメソッドを追加することです。これは、ラムダから呼び出すことができます(基本的に、関数内の割り当てを非表示にします)。

class Thing(object):
    def setSize(self, size):
        self.size = size

map(lambda i: i.setSize("big"), my_things) 
11
DirkR

__setattr__メソッドを使用して、リスト内包に属性を割り当てます。ただし、一部のSOスレッドによると、出力を使用せずにリスト内包表記を使用することはPythonicではありません。

[i.__setattr__('size', 'big') for i in my_things]
2
garnertb

これはmap()またはリスト内包表記の使用に関する問題だと思います。

完全にではありません。

my_things[:] = map(...)

多分これはpython3で:

[dict(**i.__dict__, size='big') for i in my_things]

または

map(lambda x: dict(**x.__dict__, size='big'), my_things)

もし私がオブジェクトでない辞書なら

[dict(**i, size='big') for i in my_things]

python2上

[dict(i.copy(), size='big') for i in my_things]  # isinstance(i, dict)
[dict(i.__dict__.copy(), size='big') for i in my_things]  # isinstance(i, object)
0
mackjoner