Добавление элементов подсписков на основе индексации по условию в python

У меня есть список, как показано ниже

a=[['a',1,2,1,3],['b',1,3,4,3],['c',1,3,4,3]]
b=[['b',1,3,4,3],['c',1,3,4,3]]

Я хочу добавить элементы на основе индекса, если 1-й элемент подсписка совпадает с другим элементом подсписка списка

попробовал с ниже:

from operator import add 

res_list1=[]
    for a1 in a:
        for b1 in b:
            if a1[0]==b1[0]:
                res_list = [map(add, a1[1:], b1[1:])]
                res = [[a1[0],i,j,k,l] for i,j,k,l in res_list]
                res_list1.append(res[0])
            else:
                res_list=a1
                res_list1.append(res_list)

    print res_list1

но вывод, как показано ниже:

res_list1=[['a', 1, 2, 1, 3], ['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['b', 1, 3, 4, 3], ['c', 1, 3, 4, 3], ['c', 2, 6, 8, 6]]

но правильный вывод должен быть:

res_list1=[['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['c', 2, 6, 8, 6]]
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6
0
137
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете определить функцию, подобную этой:

def add_elements(a, b):
    b_dict = {i[0]: i[1:] for i in b}
    default = [0 for _ in a][:-1]
    return [i[:1] + [sum(x) for x in zip(i[1:], b_dict.get(i[0], default))] for i in a]

И вызовите его со своими списками в качестве аргументов:

add_elements(a, b)
#[['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['c', 2, 6, 8, 6]]

см. ответ @zipa для более Pythonic (эффективного, короткого, читаемого, в целом лучшего) решения с использованием словарей.

Я попытаюсь ответить, используя исходную структуру вашего собственного кода:

from operator import add

a=[['a',1,2,1,3],['b',1,3,4,3],['c',1,3,4,3]]
b=[['b',1,3,4,3],['c',1,3,4,3]]

res_list1=[]
for a1 in a:
    found_match = False
    for b1 in b:
        if a1[0]==b1[0]:
            found_match = True
            res_list = [map(add, a1[1:], b1[1:])]
            res = [[a1[0],i,j,k,l] for i,j,k,l in res_list]
            res_list1.append(res[0])
    if not found_match:
        res_list = a1
        res_list1.append(res_list)

print(res_list1)

Проблема, с которой вы столкнулись, всегда добавлялась к res_list1, каждой итерации внутреннего цикла (то есть для каждой пары (a1,b1)). что я сделал, чтобы решить эту проблему, так это "запомнить" (то есть - сохранить в логической переменной), нашли ли мы совпадение для a1 в b, и только если нет - добавить исходный список в результат

@adam-er8 +1 за простое для понимания решение для опытных практиков Python.. Однако эта строка не ясна res = [[a1[0],i,j,k,l] for i,j,k,l in res_list]. Можете ли вы уточнить это. Благодарю.

mnm 13.06.2019 10:04

@mnm Я взял из исходного фрагмента вопроса, что он делает, так это просто добавляет общую букву к элементам после их добавления. Есть гораздо более чистые способы сделать это (например, [a1[0]] + res_list), но я хотел дать ОП ответ с минимальными изменениями.

Adam.Er8 13.06.2019 10:10
Ответ принят как подходящий

Вот подход, основанный на itertools:

from operator import itemgetter
from itertools import groupby, islice

l = sorted(a+b)
[[k] + [sum(i) for i in islice(zip(*v),1,None)] for k,v in groupby(l, key=itemgetter(0))]
# [['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['c', 2, 6, 8, 6]]

Это наиболее полное решение с точки зрения гибкости для случаев, когда есть несколько подсписков с одним и тем же первым элементом индекса, например, если a=[['a',8,2,1,1],['b',1,1,3,3],['c',1,3,8,3]] и b=[['b',2,7,9,0],['c',2,8,1,4], ['a', 7,3,0,5], ['b', 6,5,0,8]], вывод будет [['a', 15, 5, 1, 6], ['b', 9, 13, 12, 11], ['c', 3, 11, 9, 7]].

Arkistarvh Kltzuonstev 13.06.2019 09:59

@yatu: Спасибо. это мне очень помогает

learningstudent 13.06.2019 10:23

Другие вопросы по теме