как сгруппировать список в список списков по нескольким условиям? - PullRequest
0 голосов
/ 16 июня 2020

Я делаю автоматизацию между Zoho Books и HelloCa sh Online Cassa System. Эта автоматизация будет автоматически регистрировать счета-фактуры, счета, расходы, а также транзакции между счетами.

У меня возникла следующая проблема:

У меня есть списки, которые мне нужно сгруппировать. вложенные списки, основанные на 3 одинаковых элементах и ​​одном другом элементе.

Индексы одних и тех же элементов всегда x[0], x[3], x[4]

Всегда индекс разных идентификаторов элементов x[1]

Пример списка списков ( 2d массив ):

[['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '10 USt (10%)', '-0.77', '-185.54', '0'],
['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]

Для группировки на основе трех одинаковых полей я использую itertools groupby function:

non_linear_list_grouped_bills = [
    list(v) for i, v in groupby(
        sorted(
            non_linear_list_bills,
            key = lambda x: (str(x[0]),str(x[3]),str(x[4]))
            ),
        lambda x: (str(x[0]),str(x[3]),str(x[4])))
    ]

Но я не могу понять, как обеспечить, чтобы в каждом списке было другое значение в x [1] ? Другими словами, три элемента одинаковые, а один другой

Списки вложенных списков должны формировать 2d массив и выглядеть как следует :

[['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '10 USt (10%)', '-0.77', '-185.54', '0']],

[['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]

Как этого добиться?

Ответы [ 3 ]

1 голос
/ 16 июня 2020

Иногда мы группируем одно и то же вместе, поэтому вы используете groupby, а ключ - x [0], x [3] и x [4].

Перед тем, как groupby вы отсортировали список, в этом нет необходимости, по умолчанию groupby сначала выполнит сортировку.

Теперь вы хотите сгруппировать по разным элементам, я думаю, никто не может сказать, какие элементы должны быть сгруппированы вместе.

Вам лучше создать другое поле, например x [5], чтобы указать, что это за группа. Таким образом, вы можете сгруппировать их с помощью клавиши x [5].

0 голосов
/ 16 июня 2020

Я пробовал это, и у меня это сработало:

from itertools import groupby

inList = [
['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '20 USt (20%)', '-29.5', '-185.54', '0'], 
['111127', '10 USt (10%)', '-0.77', '-185.54', '0'], 
['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]

tmp =[(k, list(v)) 
  for k, v in groupby(sorted(inList, 
      key = lambda x: (str(x[0]),str(x[3]),str(x[4]))),
    lambda x: (str(x[0]),str(x[1]),str(x[3]),str(x[4])))]

tmp имеет все возможные ключи:

[(('111127', '20 USt (20%)', '-185.54', '0'),
  [['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
   ['111127', '20 USt (20%)', '-29.5', '-185.54', '0']]),
 (('111127', '10 USt (10%)', '-185.54', '0'),
  [['111127', '10 USt (10%)', '-0.77', '-185.54', '0'],
   ['111127', '10 USt (10%)', '-0.77', '-185.54', '0']])]

Затем

listOfKeys = [(key, value) for key, value in tmp]
tmp2 = [(k, list(v)) 
  for k, v in groupby(listOfKeys, 
    lambda key: (key[0][0], key[0][2], key[0][3]))]

tmp2 группирует похожие ключи (имеют одинаковые x[0], x[3] и x[4]) и выглядит следующим образом:

[(('111127', '-185.54', '0'),
  [(('111127', '20 USt (20%)', '-185.54', '0'),
    [['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
     ['111127', '20 USt (20%)', '-29.5', '-185.54', '0']]),
   (('111127', '10 USt (10%)', '-185.54', '0'),
    [['111127', '10 USt (10%)', '-0.77', '-185.54', '0'],
     ['111127', '10 USt (10%)', '-0.77', '-185.54', '0']])])]

Наконец, outList дает вам что вы хотели (в соответствии с моим пониманием)

outList = []
for key, subKeys in tmp2:
  start = len(outList)
  for k, elements in subKeys:
    for idx, element in enumerate(elements):
      index = start + idx
      if (index >= len(outList)):
        outList.append([element])
      else :
        outList[index].append(element)

результат такой, как вы хотите

[[['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
  ['111127', '10 USt (10%)', '-0.77', '-185.54', '0']],
 [['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
  ['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]]

Вы можете поиграть с этим блокнотом Google Colab где все перепробовал

0 голосов
/ 16 июня 2020

Вам нужно что-то вроде этого,

l1=[['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '20 USt (20%)', '-29.5', '-185.54', '0'],
['111127', '10 USt (10%)', '-0.77', '-185.54', '0'],
['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]
def sepk(l1):
    l2=[]
    l3=[]
    for i in l1:
        if i in l2:
            l3.append(i)
        else:
            l2.append(i)
    return l2,l3

print(sepk(l1))

вывод:

[['111127', '20 USt (20%)', '-29.5', '-185.54', '0'], ['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]
 [['111127', '20 USt (20%)', '-29.5', '-185.54', '0'], ['111127', '10 USt (10%)', '-0.77', '-185.54', '0']]

дайте комментарий, если я ошибаюсь!

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