web-dev-qa-db-ja.com

pythonリストの特定のインデックスの値を置き換える方法は?

リストがある場合:

to_modify = [5,4,3,2,1,0]

次に、他の2つのリストを宣言します。

indexes = [0,1,3,5]
replacements = [0,0,0,0]

to_modifyの要素をindexesのインデックスとして取得し、to_modifyの対応する要素をreplacementsに設定するにはどうすればよいですか、つまり、実行後、indexes[0,0,3,0,1,0]

どうやら、私はforループを介してこれを行うことができます:

for ind in to_modify:
    indexes[to_modify[ind]] = replacements[ind]

しかし、これを行う他の方法はありますか? operator.itemgetterを使用できますか?

21
Alcott

コードの最大の問題は、コードが読めないことです。 Pythonコードルール1、読みにくい場合、誰もそれから有用な情報を取得するのに十分な時間を見ない。常に説明的な変数名を使用する。ほとんどキャッチしなかったあなたのコードのバグ、良い名前、スローモーションリプレイスタイルでもう一度見てみましょう:

to_modify = [5,4,3,2,1,0]
indexes = [0,1,3,5]
replacements = [0,0,0,0]

for index in indexes:
    to_modify[indexes[index]] = replacements[index]
    # to_modify[indexes[index]]
    # indexes[index]
    # Yo dawg, I heard you liked indexes, so I put an index inside your indexes
    # so you can go out of bounds while you go out of bounds.

わかりやすい変数名を使用すると明らかなように、インデックスのリスト自体からの値でインデックスを作成しますが、この場合は意味がありません。

また、2つのリストを並行して繰り返し処理する場合は、Zip関数(またはメモリ消費が心配な場合はizipを使用しますが、私はそれらの繰り返しの純粋主義者ではありません)。代わりにこれを試してください。

for (index, replacement) in Zip(indexes, replacements):
    to_modify[index] = replacement

あなたの問題が数字のリストだけで機能している場合、@ steabertはあなたがそのnumpyのもので探していた答えを持っていると思います。ただし、numpy配列の要素としてシーケンスまたは他の可変サイズのデータ​​型を使用することはできません。そのため、変数to_modifyにはそのようなものがあります。おそらくforループを使用するのが最善です。

30

numpyには、他のリスト/配列をインデックスとして使用できる配列があります。

import numpy
S=numpy.array(s)
S[a]=m
18
steabert

なぜだけではありません:

map(s.__setitem__, a, m)
6
eph

少し遅くなりますが、読みやすいと思います:

>>> s, l, m
([5, 4, 3, 2, 1, 0], [0, 1, 3, 5], [0, 0, 0, 0])
>>> d = dict(Zip(l, m))
>>> d  #dict is better then using two list i think
{0: 0, 1: 0, 3: 0, 5: 0}
>>> [d.get(i, j) for i, j in enumerate(s)]
[0, 0, 3, 0, 1, 0]
2
utdemir

インデックスの場合:

これにより、indexaの-​​elementsの値を取得するため、それらをインデックスとして使用することは望ましくありません。 Pythonでは、実際にコンテナを反復処理することでコンテナを反復処理します。

「しかし、待って」とあなたは言います、「aのこれらの要素のそれぞれについて、mの対応する要素を操作する必要があります。インデックスなしでどのように行うのですか?」

シンプル。 amをペアのリスト(aの要素、mの要素)に変換し、ペアを反復処理します。これは簡単です-組み込みライブラリ関数Zipを次のように使用するだけです:

_for a_element, m_element in Zip(a, m):
  s[a_element] = m_element
_

意図したとおりに機能させるには、繰り返し処理するインデックスのリストを取得する必要があります。これは実行可能です。たとえば、range(len(a))を使用できます。しかし、それをしないでください!それは、Pythonで物事を行う方法ではありません。実際に、反復したいものを直接反復することは、心を解放する美しいアイデアです。

operator.itemgetterはどうですか

ここではあまり関係ありません。 _operator.itemgetter_の目的は、コールバック(たとえば、「キー」 '並べ替えまたは最小/最大操作用)。ここで使用した場合、ループを介して毎回再呼び出しして新しいアイテムゲッターを作成する必要があります。これにより、すぐに一度使用して破棄できるようになります。コンテキストでは、それはただ忙しい仕事です。

1
Karl Knechtel

operator.setitemを使用できます。

from operator import setitem
a = [5, 4, 3, 2, 1, 0]
ell = [0, 1, 3, 5]
m = [0, 0, 0, 0]
for b, c in Zip(ell, m):
    setitem(a, b, c)
>>> a
[0, 0, 3, 0, 1, 0]

ソリューションよりも読みやすく、効率的ですか?私はわかりません!

0

辞書を使って解決できます

to_modify = [5,4,3,2,1,0]
indexes = [0,1,3,5]
replacements = [0,0,0,0]

dic = {}
for i in range(len(indexes)):
    dic[indexes[i]]=replacements[i]
print(dic)

for index, item in enumerate(to_modify):
    for i in indexes:
        to_modify[i]=dic[i]
print(to_modify)

出力は

{0: 0, 1: 0, 3: 0, 5: 0}
[0, 0, 3, 0, 1, 0]
0