简体   繁体   中英

How to get some values from nested list and add to list

I have a nested list where I receive a data, but that list can change itself. How to get some values if list changes?

alltext=[{
    "name": "sample string 1",
    "relationships": [
        {
            "isBlocked": False,
            "orderIndex": 1,
            "relationship": {
                "debts": [
                    {
                        "currency": {
                            "id": "sample string2",
                            "isoCode": "string",
                            "isoNumber3": "string",
                            "name": "string"
                        },
                        #"sum"#: 0.0
                    }
                ],
                "deferment": 90,
                "id": "string",
                #"name"#: "string 1",
                "overdueDebts": [
                    {
                        "currency": {
                            "id": "string",
                            "isoCode": "string",
                            "isoNumber3": "string",
                            "name": "string"
                        },
                        #"sum"#: 1000.0
                    }
                ],
                "vendorId": "string"
            }
        },

        {
            "isBlocked": False,
            "orderIndex": 2,
            "relationship": {
                "debts": [
                    {
                        "currency": {
                            "id": "string",
                            "isoCode": "string",
                            "isoNumber3": "string",
                            "name": "string"
                        },
                        #"sum"#: 0.0
                    }
                ],
                "deferment": 90,
                "id": "string",
                "limit": 0.0,
                #"name"#: "string ",
                "overdueDebts": [
                    {
                        "currency": {
                            "id": "string",
                            "isoCode": "string",
                            "isoNumber3": "string",
                            "name": "string"
                        },
                        #"sum"#: 2000.0
                    }
                ],
                "vendorId": "string"
            }
        }
    ]
}
]

I was trying to do it as example it

for i in range(len(alltext)):
        ordersname.append(alltext[i]['relationships'][0]['relationship']['name'])

or like it:

Debts.append([routeDict['sum'] for routeDict in alltext[i]['relationships'][0]['relationship']['debts']])

OverdueDebts.append([routeDict['sum'] for routeDict in alltext[i]['relationships'][0]['relationship']['overdueDebts']])

I have understandent that I think that all because [0] and I always take first values. If O delete [0] I receive error TypeError: list indices must be integers or slices, not str

I want to get sum from Debts and OverdueDebts and Name from all relationship(I tagged all things that I want to have

I tagged this as a map-reduce problem. Map-reduce is a common problem with many available solutions. I encourage you to look through some examples. In the future, post what you have tried.

Here is one way to map-reduce your dictionary. I instantiate a new empty array, iterate through each relationship, and then add a new dict to the array.

array_of_dicts = []

for relationship in main_dict['relationships']:
    r = relationship['relationship']
    debts = sum([debt['sum'] for debt in r['debts']])
    overdue = sum([debt['sum'] for debt in r['overdueDebts']])
    array_of_dicts.append({
        'name': r['name'],
        'debt': debts,
        'overdue': overdue
    })

Python offers many shortcuts for map-reduce such as lambda functions and built-ins. I am using some list-comprehensions but could just as easily use a dict-comprehension.

Let me add some functional way (since we want to learn diverse strategies to solve this)

import toolz.curried
from operator import itemgetter

get_name = toolz.curried.get_in(['relationship', 'name'])

get_debts = toolz.curried.get_in(['relationship', 'debts'])
get_overdue = toolz.curried.get_in(['relationship', 'overdueDebts'])

debt_sum = toolz.compose_left(get_debts, toolz.curried.map(itemgetter('sum')), sum)
overdue_sum = toolz.compose_left(get_overdue, toolz.curried.map(itemgetter('sum')), sum)

collect_info = toolz.juxt(get_name, debt_sum, overdue_sum)

list(map(collect_info, blubb['relationships']))

Poor soul who needs to read the code ;-) ... so @solbs's answer is way more readable than this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM