7

リストがあります: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]

ワンライナー、またはこれを行うためのより簡単な方法を探しています。より一般的で柔軟な回答が望ましいです。

4

6 に答える 6

8

特に、のかなりの部分を置き換えるので、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
于 2013-01-16T02:31:14.427 に答える
2
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])
于 2013-01-16T02:24:29.367 に答える
1

を使用することに反対しない場合、Numpy はこれをサポートしますnp.ndarray

>>> a = np.zeros(5)
>>> a[[0,1,3]] = 100
>>> a
array([ 100.,  100.,    0.,  100.,    0.])
于 2013-01-16T02:26:52.727 に答える
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.dequedeque0mapsixmapitertools.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]
于 2013-01-16T02:31:49.073 に答える
0

私はリスト内包が好きです:

[100 if index in [1, 4] else 0 for index, x in enumerate(mylist) ]
于 2013-01-16T02:32:46.410 に答える
0

これはあなたが探しているものですか?変更するインデックスのリストを作成し、そのリストをループして値を変更します。

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]
于 2013-01-16T02:20:47.477 に答える