Обновите один список значениями из другого списка в Python

#python #python-3.x

#python #python-3.x

Вопрос:

У меня есть список кортежей, содержащих пользовательские данные, как указано ниже (2-е значение кортежа — возраст)

 l1 = [('uid1','23','F'),('uid2','35','M'),('uid3','25','M'),.....]
  

Мне нужно обновить значения возраста из другого списка, как указано ниже:

 l2 = [('uid1','24'),('uid2','37'),....]
  

Кортежи в l2 имеют только два элемента, размер l2 меньше, чем l1, но не все значения l2 могут присутствовать в l1, поэтому необходимо будет обновить только те значения, которые присутствуют в l1. Как создать новый список l3, как показано ниже?

 l3 = [('uid1','24','F'),('uid2','37','M'),('uid3','25','M'),.....]
  

Пожалуйста, предложите, как это сделать.

#Обновление 1 Я попытался преобразовать l2 в словарь:

 d = {x[0]:x[1] for x in l2}
  

и затем,

 l3 = [(x[0],d[x[0]],x[2]) for x in l1]
  

но он выдает ошибку, в которой соответствующее d[x[0]] значение не найдено d . Как избежать этого и сохранить старое значение?

Комментарии:

1. Похоже, вы должны использовать dicts вместо кортежей…

2. @Tomerikoo Я попробовал это, и я обновил исходное сообщение

3. Можете ли вы привести четкий пример ввода / вывода? Вам нужно l3 иметь все значения l1 с теми, которые также находятся в l2 обновлении, или значения l2 с теми, которые также находятся в l1 обновлении?

4. @Tomerikoo l3 должен содержать все кортежи как l1 со значениями возраста, обновленными с l2, где это возможно. Если в l2 нет кортежа (идентификатора пользователя), который присутствует в l1, он не будет обновляться в l3 и будет сохранен как есть.

Ответ №1:

Должно работать следующее:

 d2={i[0]:i[1] for i in l2}

l3=[]

for i in l1:
    if i[0] in d2:
        l3.append((i[0], d2[i[0]], i[2]))
    else:
        l3.append(i)
  

Для

 l1=[('uid1', '23', 'F'), ('uid2', '35', 'M'), ('uid3', '25', 'M')]
l2=[('uid1', '24'), ('uid2', '37')]
  

Вывод будет:

 >>> print(l3)
[('uid1', '24', 'F'), ('uid2', '37', 'M'), ('uid3', '25', 'M')]
  

Ответ №2:

Чтобы избежать O(n^2) времени выполнения (для каждого введенного кортежа l1 проверьте, включен ли он l2 ), лучше использовать словарь для сопоставления name с age:

 l2_d = dict(l2)
  

И теперь легче проверить, имеет ли определенное имя возраст замены. Мы выполняем итерацию l1 и берем соответствующий возраст из l2 или оригинал, если он не существует l2 . Затем просто добавьте кортежи в новый список с соответствующим возрастом:

 l3 = []

for name, age, gender in l1:
    age = l2_d.get(name, age)
    l3.append((name, age, gender))
  

Затем это также может быть сведено к пониманию списка, но оно может находиться на границе читаемости:

 l3 = [(name, l2_d.get(name, age), gender) for name, age, gender in l1]