2011-09-04 17 views
3

私はタプルで、このリストをしました:Python:リスト要素を変更する正しい方法は何ですか?

l = [('a','b'),('c','d'),('e','f')] 

そして、二つのパラメータ:キーの値、および変更する新しい値。

f = lambda t,k,v: t[0] == k and (k,v) or t 
new_list = [f(t,key,new_value) for t in l] 
print new_list 

new_list = [] 
for i in range(len(l)): 
    elem = l.pop() 
    if elem[0] == key: 
     new_list.append((key,new_value)) 
    else: 
     new_list.append(elem) 
print new_list 

しかし、私はPythonで新たなんだ、と知っていない:例えば、

key = 'a' 
new_value= 'B' # it means, modify with 'B' the value in tuples where there's an 'a' 

私はこの二つのオプション(両方の作品を)しましたもしその権利があれば。

私を助けることができますか?ありがとうございました!

+5

辞書のような機能が必要な場合は、[辞書](http://docs.python.org/tutorial/datastructures.html#dictionaries)を使用してください。 。明らかに、これはキーが一意でなければならないことを意味します。それがあなたの要求に反するかどうかわかりません – NullUserException

+0

ありがとう、私は辞書を知っています。より一般的な質問です。リスト内の要素を変更する方法です。 – santiagobasulto

+0

これはaを変更しません。リストを作成すると、新しいコピーが作成されます。どちらがいいですか? –

答えて

2

既存のリストを変更するには、リストの割り当てを使用します。

>>> l = [('a','b'),('c','d'),('e','f')] 
>>> l[0] = ('a','B') 
>>> print l 
[('a', 'B'), ('c', 'd'), ('e', 'f')] 

私は通常、例えば、理解を使用して新しいリストを作成することを好みます最初のコメントは、既に述べたように

[(key, new_value) if x[0] == key else x for x in l] 

はしかし、それはあなたがリストは、あなたが本当に代わりのための辞書を使用しなければならない何かを作るしようとしているように聞こえます。

+0

あなたは本当ですか? 'l [0] =( 'a'、 'B')'を意味していませんでしたか? – Tadeck

+0

o_O確かに..愚かな理由のために私は平らなリストを考えていましたが、とにかくタプルを書きました。ありがとう。 – wim

+0

本当に簡単な解決策です。ありがとう! – santiagobasulto

3

新しいリストを作成するには、リストの内包が行うだろう:

In [102]: [(key,'B' if key=='a' else val) for key,val in l] 
Out[102]: [('a', 'B'), ('c', 'd'), ('e', 'f')] 

を所定の位置にリストを変更するには:

l = [('a','b'),('c','d'),('e','f')] 

for i,elt in enumerate(l): 
    key,val=elt 
    if key=='a': 
     l[i]=(key,'B') 
print(l)    
# [('a', 'B'), ('c', 'd'), ('e', 'f')] 
+0

うわー、それらの "インラインifs"も列挙関数を知らなかった。ありがとう! – santiagobasulto

+0

@santiagobasulto:私が手伝ってくれてうれしいです。 "インラインifs"は[条件式](http://docs.python.org/reference/expressions.html#conditional-expressions)またはPythonの三項式と呼ばれます。 – unutbu

2

ここで私が使用するアプローチです。

>>> l = [('a','b'),('c','d'),('e','f')] 
>>> key = 'a' 
>>> new_value= 'B' 
>>> for pos in (index for index, (k, v) in enumerate(l) if k == key): 
...  l[pos] = (key, new_value) 
...  break 
... else: 
...  l.append((key, new_value)) 
... 
>>> l 
[('a', 'B'), ('c', 'd'), ('e', 'f')] 

これは非常によく似ていますが、OrderedDictです。保存された順序付きのキーと値のペア。それはあなたのニーズに合っている場合は、そのを見て、見たいかもしれません

編集:それは少し少ない奇妙に見えるかもしれませんので、for: ... break ... else:で... try:except StopIteration:を取り替えました。

+0

あなたは複雑な解決策を検討しています! –

+0

私はこれが全く複雑であるとは思わない。 'list.index'は利用できません。なぜなら、キーと同じではなく、キーと何らかの形で*対応する要素を探しているからです。 'enumerate'はかなり正常です。私は' generator ...> next() '以外のジェネレータから*最初の要素*を取得し、見つからなければ例外をキャッチする代替イディオムがないことを知っています。他の選択肢は、不必要に言い方をしたり、中間リストを生成したりするでしょう。 – SingleNegationElimination

+0

PythonのZenが複雑なことよりも複雑なことを話すように、私はそれを複雑にします。単純な解決策があるときは、 ' .next()'を使うのではなく完全な 'for'ループを繰り返し、' StopIteration'を捕まえることに対処する必要があります。あなたのソリューションが正確性を検証するために何をしていたのか簡単に考えなければなりませんでしたが、私のソリューションや他の同様のものを見て、すぐに何が行われているのかを理解することができます。 'for-if'スタイルのエラーがもっとはっきりしているように思えます。 –

4

ここでは、アイテムをインプレースで変更する1つの解決策があります。

def replace(list_, key, new_value): 
    for i, (current_key, current_value) in enumerate(list_): 
     if current_key == key: 
      list_[i] = (key, new_value) 

それとも、それはそこにない場合は追加する、

def replace_or_append(list_, key, new_value): 
    for i, (current_key, current_value) in enumerate(list_): 
     if current_key == key: 
      list_[i] = (key, new_value) 
      break 
    else: 
     list_.append((key, new_value)) 

使用法:

>>> my_list = [('a', 'b'), ('c', 'd')] 
>>> replace(my_list, 'a', 'B') 
>>> my_list 
[('a', 'B'), ('c', 'd')] 

新しいリストを作成したい場合は、リストの内包が最も簡単です。

>>> my_list = [('a', 'b'), ('c', 'd')] 
>>> find_key = 'a' 
>>> new_value = 'B' 
>>> new_list = [(key, new_value if key == find_key else value) for key, value in my_list] 
>>> new_list 
[('a', 'B'), ('c', 'd')] 

そして、あなたはそれがなかった場合、それは追加したい場合は、

>>> if len(new_list) == len(my_list): 
...  new_list.append((find_key, new_value)) 

は(私はlからあなたの変数名を変更したにも注意してください。lはあまりにも簡単に混乱しI1であります

関連する問題