#python #list #multidimensional-array
#python #Список #многомерный массив
Вопрос:
следующее:
gnucashumsaetze = [
['2020-11-27', 'Essen', '4.53'],
['2020-11-27', 'Essen', '10.67'],
['2020-11-30', 'Essen', '4.80'],
['2020-11-30', 'Lebensmittel', '2.78'],
['2020-11-30', 'Essen', '2.31'],
['2020-11-30', 'Kosmetik', '5.58'],
['2020-12-01', 'Essen', '11.23'],
]
onlineumsaetze = [
['2020-11-27', 'EDEKA ERNST HAUPTBAHNH / MUENCHEN', '4.53']
['2020-11-27', 'Netto Marken-Discount / Ingolstadt', '10.67']
['2020-11-30', 'MUELLER GMBH amp; CO.KG / NUERNBERG', '4.80']
['2020-11-30', 'Netto Marken-Discount / Frankfurt', '2.31']
['2020-11-30', 'Rossmann 2380 / Ingolstadt', '5.58']
['2020-11-30', 'ALIEXPRESS.COM / Luxembourg', '22.46']
['2020-12-01', 'EDEKA BRAUN / INGOLSTADT', '11.23']
['2020-12-02', 'EDEKA ERNST HAUPTBAHNH / MUENCHEN', '7.03']
]
я хотел бы сравнить два 2d-списка и вывести разные. Но второй столбец (строка [1]) сравнивать не следует. Вот так:
['2020-11-30', 'ALIEXPRESS.COM / Luxembourg', '22.46']
['2020-12-01', 'EDEKA BRAUN / INGOLSTADT', '11.23']
['2020-12-02', 'EDEKA ERNST HAUPTBAHNH / MUENCHEN', '7.03']
то, что я уже пробовал, это; к сожалению, катастрофа:
fehlende_rows = (set((row[0] for row in onlineumsaetze),(row[2] for row in onlineumsaetze)) - set((row[0] for row in gnucashumsaetze),(row[2] for row in gnucashumsaetze)))
print(fehlende_rows)
Комментарии:
1. Разрешено ли вам изменять структуру данных? Например, преобразовать эти списки в dicts?
2. Что значит «выводить разные»? Вы имеете в виду, что хотите вывести строку
onlineumsaetze
только из того, чтоgnucashumsaetze
не содержит строк с одинаковой датой и числовым значением в третьем столбце?3. @Diptangsu Госвами, К сожалению, нет. Эти данные копируются с веб-страницы HTML.
4. @Pranav Hosangadi, да, точно, в первом и третьем.
Ответ №1:
Я нахожу очень полезным сначала записать полный цикл, а затем, по возможности, свести его к пониманию списка.
Вероятно, лучшим способом сделать это было бы выполнить итерацию gnucashumsaetze
и создать словарь string->set, который содержит даты в качестве ключей и числа в качестве элементов набора.
gnucashumsaetze_dict = {}
for g in gnucashumsaetze:
date, val = g[0], g[2]
# Maybe you want to do val = float(g[2]) instead?
if date not in gnucashumsaetze_dict:
gnucashumsaetze_dict[date] = set()
gnucashumsaetze_dict[date].add(val)
gnucashumsaetze_dict
теперь:
{'2020-11-27': {'10.67', '4.53'},
'2020-11-30': {'2.31', '2.78', '4.80', '5.58'},
'2020-12-01': {'11.23'}}
Затем выполните итерацию по каждой строке onlineumsaetze
и добавьте ее в новый список, только если выполнено требуемое условие.
new_onlineumsaetze = []
for o in onlineumsaetze:
date, val = o[0], o[2]
# if date is not in gnucashumsaetze_dict, return empty set
vals = gnucashumsaetze_dict.get(date, set())
if val not in vals:
new_onlineumsaetze.append(o)
new_onlineumsaetze
теперь:
[['2020-11-30', 'ALIEXPRESS.COM / Luxembourg', '22.46'],
['2020-12-02', 'EDEKA ERNST HAUPTBAHNH / MUENCHEN', '7.03']]
['2020-12-01', 'EDEKA BRAUN / INGOLSTADT', '11.23']
Строка пропускается, потому gnucashumsaetze
что содержит запись для ['2020-12-01', 'Essen', '11.23']
Теперь, когда вы написали это как обычный цикл for, легче свести это к пониманию списка.
new_onlineumsaetze = [o for o in onlineumsaetze if o[2] not in gnucashumsaetze_dict.get(o[0], set())]
Ответ №2:
Для решения этой проблемы я буду использовать понимание списка
сначала создайте два набора, используя только column0 и column2
gnucashumsaetze_set = set([(row[0], row[2]) for row in gnucashumsaetze])
onlineumsaetze_set = set([(row[0], row[2]) for row in onlineumsaetze])
Затем мы получаем разницу между этими двумя наборами
diff_ = onlineumsaetze_set.difference(gnucashumsaetze_set)
для получения конечного результата мы ищем строки в onlineumsaetze, которые совпадают в column0 и column2 с полученными нами данными.
res = [row for row in onlineumsaetze if (row[0], row[2]) in diff_]
print(res)
результат
[['2020-11-30', 'ALIEXPRESS.COM / Luxembourg', '22.46'], ['2020-12-02', 'EDEKA ERNST HAUPTBAHNH / MUENCHEN', '7.03']]