リストがあります:mylist = [0, 0, 0, 0, 0]
選択した要素のみを置き換えたい、たとえば、1 番目、2 番目、4 番目の要素を共通の数字A = 100
.
これを行う1つの方法:
mylist[:2] = [A]*2
mylist[3] = A
mylist
[100, 100, 0, 100, 0]
ワンライナー、またはこれを行うためのより簡単な方法を探しています。より一般的で柔軟な回答が望ましいです。
リストがあります:mylist = [0, 0, 0, 0, 0]
選択した要素のみを置き換えたい、たとえば、1 番目、2 番目、4 番目の要素を共通の数字A = 100
.
これを行う1つの方法:
mylist[:2] = [A]*2
mylist[3] = A
mylist
[100, 100, 0, 100, 0]
ワンライナー、またはこれを行うためのより簡単な方法を探しています。より一般的で柔軟な回答が望ましいです。
特に、のかなりの部分を置き換えるので、list
これを不変に行います。
mylist = [100 if i in (0, 1, 3) else e for i, e in enumerate(mylist)]
Pythonでは、新しいものを作成することlist
はワンライナーであることが意図されていますが、を変更list
するには明示的なループが必要です。通常、どちらが必要かわからない場合は、新しいものが必要ですlist
。(場合によっては、速度が遅くなったり、複雑になったり、同じものへの参照があり、変更されているlist
ことを確認する必要がある他のコードがある場合などがあります。そのため、「常に」ではなく「通常」になります。)
これを複数回実行したい場合は、ボラティリティが示唆するように、関数でまとめます。
def elements_replaced(lst, new_element, indices):
return [new_element if i in indices else e for i, e in enumerate(lst)]
私は個人的にそれをジェネレーターにするので、リストを返す代わりに反復を生成します。たとえそのように愚かであるという理由だけで、それが必要になることは決してないでしょう。しかし、実際にそれが必要な場合:
myiter = (100 if i in (0, 1, 3) else e for i, e in enumerate(mylist))
または:
def elements_replaced(lst, new_element, indices):
for i, e in enumerate(lst):
if i in indices:
yield new_element
else:
yield e
def replace_element(lst, new_element, indices):
for i in indices:
lst[i] = new_element
return lst
ただし、これは間違いなくより一般的なソリューションであり、ワンライナーではありません。たとえば、あなたの場合、次のように呼び出します。
mylist = replace_element(mylist, 100, [0, 1, 3])
を使用することに反対しない場合、Numpy はこれをサポートしますnp.ndarray
。
>>> a = np.zeros(5)
>>> a[[0,1,3]] = 100
>>> a
array([ 100., 100., 0., 100., 0.])
これの大ファンではありませんが、これを試すことができます(上記のすべてがはるかに簡潔で読みやすいと思いますが):
In [22]: from operator import setitem
In [23]: mylist = [0, 0, 0, 0, 0]
In [24]: indeces_to_replace = [0, 1, 3]
In [25]: _ = map(lambda x: setitem(mylist, x, 100), indeces_to_replace)
In [26]: mylist
Out[26]: [100, 100, 0, 100, 0]
可読性が疑わしく、インポートが必要なことを除けば、@ abarnertはいくつかの追加の問題を指摘しました。つまりmap
、不要なリストが作成され(それでも破棄されますが、それでも作成されます)、 Python3_
では機能しません。 Python3.xのmap
イテレータ。6つのモジュールを使用して、Python2.xからPython3.xでの動作をシミュレートできます。また、 (@ abarnertによって提案されているように)map
組み合わせて、メモリに追加のリストを作成せずに同じ出力を実現できます。最大のアイテムを含むことができるものは、イテレータから受け取ったすべてのものを破棄します(で、を使用してシミュレートされることに注意してください)。collections.deque
deque
0
map
six
map
itertools.imap
繰り返しますが、これを使用する必要はまったくありません-上/下のすべてのソリューションが優れています:)
In [1]: from collections import deque
In [2]: from six.moves import map
In [3]: from operator import setitem
In [4]: mylist = [0, 0, 0, 0, 0]
In [5]: indeces_to_replace = [0, 1, 3]
In [6]: deque(map(lambda x: setitem(mylist, x, 100), indeces_to_replace), maxlen=0)
Out[6]: deque([], maxlen=0)
In [7]: mylist
Out[7]: [100, 100, 0, 100, 0]
私はリスト内包が好きです:
[100 if index in [1, 4] else 0 for index, x in enumerate(mylist) ]
これはあなたが探しているものですか?変更するインデックスのリストを作成し、そのリストをループして値を変更します。
els_to_replace = [0, 1, 3]
mylist = [0, 0, 0, 0, 0]
for index in els_to_replace:
mylist[index] = 100
mylist
Out[9]: [100, 100, 0, 100, 0]