Python matching lists are not equal in length to columns

Can you take a list of lists of unequal length and write it in a row of columns when matching with the order of another list?

order = ['bx', 'cs', 'lb', 'pc']

totals = [
    [{'unit': 'pc', 'sum': Decimal('3.00')}],
    [{'unit': 'bx', 'sum': Decimal('3.00')}, {'unit': 'pc', 'sum': Decimal('16.00')}],
    [{'unit': 'bx', 'sum': Decimal('6.00')}, {'unit': 'lb', 'sum': Decimal('24.00')}, {'unit': 'pc', 'sum': Decimal('63.00')}],
    [{'unit': 'pc', 'sum': Decimal('36.00')}],
    [{'unit': 'bx', 'sum': Decimal('31.00')}]
]

desired_format = [
    ['', '', '', '3.00 pc'],
    ['3.00 bx', '', '', '16.00 pc'],
    ['6.00 bx', '', '24.00 lb', '63:00 pc'],
    ['', '', '', '36:00 pc'],
    ['31.00 bx', '', '', ''],
]

I tried below, but it does not work as desired if all 4 units are in order missing.

desired_format = [[]]
for total in totals:
    data = []
    for idx, um in enumerate(total):
        if um['unit'] == order[idx]:
            data.append(str(um['sum'] + ' ' + str(um['unit'])))
        else:
            data.append('')
    desired_format.append(data)

I also tried this, which ends up with too many empty columns and uneven / unordered columns

desired_format = [[]]
for total in totals:
    data = []
    for um in total:
        for unit in order:
            if um['unit'] == unit:
                data.append(str(um['sum'] + ' ' + str(um['unit'])))
            else:
                data.append('')
    desired_format.append(data)
+4
source share
5 answers

I suggest you the following code based on your original post:

desired_format = []
for total in totals:
    data = []
    for orderValue in order:
        found = False
        for um in total:
            if um['unit'] == orderValue:
                found = True
                break
        if found:
            data.append(str(um['sum'] + ' ' + str(um['unit'])))
        else:
            data.append('')
    desired_format.append(data)

print(desired_format)
0
source

This is not the most effective method.

converters = [{dict['unit']: dict['sum'] for dict in total} for total in totals]
desired_format = [[str(converter[item])+' '+item if item in converter else '' for item in order] for converter in converters]

The idea is that your totals are a list of dictionaries. Converters turn it into a list of dictionaries using list comprehension

, : , , ''

, , , .

0

, ( ).

desiredFormat = [[]], , . [], .

, , , .

:

desired_format = []
for total in totals:
    data = [''] * len(order)
    for um in total:
        for i, unit in enumerate(order):
            if um['unit'] == unit:
                data[i] = str(um['sum']) + ' ' + str(um['unit'])
    desired_format.append(data)

, , .

0

collections.defaultdict:

from collections import defaultdict

d = defaultdict(list)

for idx, i in enumerate(totals):
    for j in order:
        d_item = next((str(k['sum']) + ' ' + j for k in i if k['unit'] == j), '')
        d[idx].append(d_item)

res = [d[i] for i in range(len(totals))]

# [['', '', '', '3.00 pc'],
#  ['3.00 bx', '', '', '16.00 pc'],
#  ['6.00 bx', '', '24.00 lb', '63.00 pc'],
#  ['', '', '', '36.00 pc'],
#  ['31.00 bx', '', '', '']]
0

The next solution is based on creating a table of size len(order)x len(totals)originally populated with a default value ''. Then we populate the table based on the known values ​​in totals, leaving the rest as ''.

# Have your order as dict for quick lookup
order_keys = dict(map(reversed, enumerate(order)))
# This output the indexing: {'bx': 0, 'cs': 1, 'lb': 2, 'pc': 3}

# Create the empty table for the desired output, default value will be ''
output = [[''] * len(order_keys) for _ in range(len(totals))]
# output:
# [['', '', '', ''],
#  ['', '', '', ''],
#  ['', '', '', ''],
#  ['', '', '', ''],
#  ['', '', '', '']]

for index, row in enumerate(totals):
    for col in row:
        unit = col['unit']
        output[index][order_keys[unit]] = '{} {}'.format(col['sum'], col['unit'])

# output:
# [['', '', '', '3.00 pc'],
#  ['3.00 bx', '', '', '16.00 pc'],
#  ['6.00 bx', '', '24.00 lb', '63.00 pc'],
#  ['', '', '', '36.00 pc'],
#  ['31.00 bx', '', '', '']]
0
source

Source: https://habr.com/ru/post/1694912/


All Articles