Python: Как правильно изменить элементы списка? - PullRequest
3 голосов
/ 05 сентября 2011

У меня есть этот список с кортежами:

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

И два параметра: значение ключа и новое значение для изменения. Например,

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

У меня есть два варианта (оба работают):

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 и не знаю, правильно ли это.

Вы можете мне помочь? Спасибо!

Ответы [ 4 ]

4 голосов
/ 05 сентября 2011

Вот одно решение, включающее изменение элементов на месте.

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 слишком легко спутать с I и 1, и его лучше избегать. Поэтому говорит PEP8, и я с ним согласен.)

3 голосов
/ 05 сентября 2011

Чтобы создать новый список, необходимо сделать следующее:

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')]
2 голосов
/ 05 сентября 2011

Вот подход, который я бы использовал.

>>> 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, хотя;пары ключ-значение с сохраненным порядком.Возможно, вы захотите взглянуть на это и посмотреть, подходит ли оно вам

Редактировать: Заменено try: ... except StopIteration: на for: ... break ... else:так как это может выглядеть немного менее странно.

2 голосов
/ 05 сентября 2011

Чтобы изменить существующий список, просто используйте присвоение списка, например,

>>> 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]

Но, как уже упоминалось в первом комментарии, звучит так, как будто вы пытаетесь составить список, чтобы сделать что-то, для чего вы должны использовать дикт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...