简体   繁体   中英

Iteration over a list of dictionaries

I'm trying to write a script that receives as input two lists of dictionaries, from two .csv files, checks for keys matches and gives another list of dictionaries with an output from the two lists. I have this so far:

import csv

def tabel_animals_func(file_csv):

 with open(ficheiro_csv, 'rU') as file_csv_animals:
    inputFile = csv.DictReader(file_csv_animals, delimiter=';')

    result_animals = []
    for line in inputFile:
        result_animals.append(line)
 return result_animals

def tabel_owners_func(file_csv2):

 with open(file_csv2, 'rU') as file_csv_owners:
    reader = csv.DictReader(file_csv_owners, delimiter=';')
    result_owners = []
    for line in reader:
        result_owners.append(line)
 return result_owners

def average_Age(tabela_animais, tabela_donos):

  var_owners = tabel_owners_func(tabel_owners)
  var_animals = tabel_animals_func(tabel_animals)

I need to make the third function output, a new list of dicts with the average age of the owners animals, the output is something like this:

  [{'Owners Name' : 'Jack', 'Average age' : '5'}, {'Owners Name' : 'Tom', 'Average age' : '8'}]

This is an input .csv file example, for the tabel_animals_func:

  Name of the animal;Species;Age
  Kiko;Cat;8
  Rocky;Turtle;57
  Snoopy;Dog;12
  Nemo;Fish;2
  Leonardo;Turtle;45
  Milo;Dog;9
  Raphael;Turtle;57
  Dory;Fish;4

tabel_owners_func input file:

  Owners Name;Name of the animal
  Ana;Michelangelo
  Tom;Dory
  Jack;Kiko
  Tom;Snoopy
  Eva;Rocky
  Sara;Raphael
  Jack;Nemo

First, I'd like to suggest that you merge your two CSV reading functions. If you take a step back, you'll see that those functions really just do the same thing. Combine them into a read_csv_contents function, or something.

You should probably convert the list-of-dicts returned by your animals reader into a dict-of-dicts with the animal name as the key:

var_animals = tabel_animals_func(tabel_animals)
animals = {data['Name of animal']:data for data in var_animals}

Once you have that, you can find the list of animals owned by each owner:

pets = {}
for owner in var_owners:
    o_name = owner['Owners Name']

    if o_name not in pets:
        pets[o_name] = []

    pets[o_name].append(animals['Name of animal'])

With a list of pets for each person, it should be easy to do your math:

for owner,pet_list in pets.items():
    npets = len(pet_list)
    avg_age = sum([pet['Age'] for pet in pet_list]) / npets

The advice in Austin's answer the seperate reader for csv files I replace it one function and call it read_csv . The average_age function do a lot of work. If there is somewhere you don't understand please let me know to explain it.

I think this is your solution (I'm not good at in English so I have not explain deeply);

import csv

def read_csv(filename):
    with open(filename, 'r') as file:
        input_file = csv.DictReader(file, delimiter=";")

        results = []
        for line in input_file:
            results.append(line)

    return results

def get_age(animal_name): 
    # the function calculate the age of given animal
    for a in animal_age:
        if a['Name of the animal'] == animal_name:
            return int(a['Age'])

def average_age(owners_animal):
    # the function return a list which contain all owners and its animals' average age
    results = []
    owners_list = []
    animal_list = []
    for o in owners_animal:
        if o['Owners Name'] not in owners_list:
            owners_list.append(o['Owners Name'])
            result = {'Owners Name': o['Owners Name'], 'Ages': []}
            age = get_age(o['Name of the animal']) or 0
            result['Ages'].append(age)

            results.append(result)
        else:
            for r in results:
                if r['Owners Name'] == o['Owners Name']:
                    r['Ages'].append(get_age(o['Name of the animal']))

    results = [{'Owners Name': obj.get('Owners Name'), 'Average age': int(sum(obj['Ages'])/len(obj['Ages']))} for obj in results]
    print(results)



owners_animal = read_csv("tabel_owners.csv") # the owner table
animal_age = read_csv("tabel_animals.csv") # the animal table

average_age(owners_animal)

There is a misvalue for Ana 's animal, Michelangelo doesn't appear in Age table.

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