2017-10-16 8 views
2

je 3 DB appelle retourner un tuple de tuples avec un nom, code et compte comme ceci:fusionner plusieurs listes de listes basées sur le modèle

year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '3457', 1))

month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1))

week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1))

Je dois les fusionner tous ensemble afin qu'ils aient le nom, le code et le compte pour l'année, le mois et l'hebdomadaire.

Mon problème est que s'il n'y a aucun enregistrement j'ai besoin d'insérer le nom et le code dans ET une valeur 0 pour les comptes. Le produit final devrait être quelque chose comme:

result = (('Windham', '0905', 1, 1, 0), ('Windsor Windham', '7852', 0, 0, 0), ('Washington', '3292', 0, 0, 0), 
      ('Orleans Essex', '44072', 1, 1, 0), ('Addison', '2853', 0), ('Bennington', '3778', 0), 
      ('Fanklin Grand Isle', '5560', 0, 0 0), ('Caledonia', '1992', 0, 0, 0), 
      ('Rutland', '2395', 1, 0, 0), ('Chittendon', '3367', 1, 1, 0), ('Lamoille', '5229',0, 0 0)) 

Je tentais de nid d'une boucle pour vérifier si le nom était présent dans l'appel de DB et le modèle. IF si la valeur était append DB à la liste, sinon ajoutez 0

i = 0 
for p in newlist: 
    try: 
     if p[0] == mlist[i][0]: 
      print("HERE: {} {}".format(p[0], mlist[i][0])) 
      p.append(mlist[i][-1]) 
      i += 1 
     else: 
      p.append(0) 
    except IndexError: 
     continue 

Ceci est la valeur DB AJOUT DE mais pas le zéro. Je suis sûr qu'il doit y avoir une meilleure façon de le faire et de le faire fonctionner.

Modifier

Voici le code mis à jour en fonction des réponses reçues. Pour moi, il remplace encore chaque valeur year avec un 0.

DONNÉES:

year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '0905', 0), ('Windsor Windham', '7852', 0), ('Washington', '3292', 0), ('Orleans Essex', '44072', 0), ('Chittendon', '18028633367', 1), ('Addison', '12853', 0), ('Bennington', '3778', 0), ('Caledonia', '11992', 0), ('Rutland', '1895', 0), ('Chittendon', '18367', 0), ('Lamoille', '1809', 0), ('Windham', '180905', 0), ('Windsor Windham', '180852', 0), ('Waston', '18022623292', 0), ('Orleans Essex', '18072', 0), ('Addison', '1853', 0), ('Bennington', '1778', 0), ('Fanklin Grand Isle', '18560', 0), ('Caledonia', '180292', 0), ('Rutland', '195', 0), ('Lamoille', '18229', 0)) 

month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '18028633367', 1)) 

week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '18367', 1)) 

code:

from collections import defaultdict 
joined_data = defaultdict([0, 0, 0].copy) 

for entry in year: 
    # we create the default entry by calling the defaultdict with a key 
    # and immediately grab the newly created list 
    count = joined_data[(entry[0],entry[1])] 
    # we swap *inplace* the value given by the DB query 
    count[0] = entry[2] 

# rinse and repeat with the rest of the data 
for entry in month: 
    count = joined_data[(entry[0], entry[1])] 
    count[1] = entry[2] 

for entry in week: 
    count = joined_data[(entry[0], entry[1])] 
    count[2] = entry[2] 

# Finally we format the data to the required format 
result = tuple(key+tuple(value) for key,value in joined_data.items()) 
print(result) 

Résultat:

(('Fanklin Grand Isle', '5560', 0, 1, 1), ('Windham', '0905', 0, 0, 0), ('Windsor Windham', '7852', 0, 0, 0), ('Washington', '3292', 0, 0, 0), ('Orleans Essex', '1072', 0, 0, 0), ('Chittendon', '13367', 0, 1, 1), ('Addison', '2853', 0, 0, 0), ('Bennington', '1878', 0, 0, 0), ('Caledonia', '1992', 0, 0, 0), ('Rutland', '2395', 0, 0, 0), ('Lamoille', '5229', 0, 0, 0))

+0

Bien sûr, toutes ces villes obtiennent un 'pour l'année 0' si l'année -count est '0' dans votre liste' year'. Quel résultat attendiez-vous à la place, et pourquoi? –

+0

Désolé tobias ne voulait pas éditer votre message, destiné à modifier le mien – Joe

Répondre

0

Voici une façon de traiter votre problème en utilisant un defaultdict pour éviter d'avoir à se soucier des entrées manquantes:

year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '3457', 1)) 
month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 
week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 

#I'm using a defaultdict to deal with the missing entries 
from collections import defaultdict 
joined_data = defaultdict([0,0,0].copy) 

for entry in year: 
    #we create the default entry by calling the defaultdict with a key 
    #and immediately grab the newly created list 
    count = joined_data[(entry[0],entry[1])] 
    #we swap *inplace* the value given by the DB query 
    count[0] = entry[2] 

#rinse and repeat with the rest of the data 
for entry in month: 
    count = joined_data[(entry[0],entry[1])] 
    count[1] = entry[2] 

for entry in week: 
    count = joined_data[(entry[0],entry[1])] 
    count[2] = entry[2] 

#Finally we format the data to the required format 
result = tuple(key+tuple(value) for key,value in joined_data.items()) 
print(result) 

Sortie:

>>>(('Chittendon', '3367', 0, 1, 1), ('Fanklin Grand Isle', '5560', 1, 1, 1), ('Windham', '3457', 1, 0, 0)) 
+0

Cela semble prometteur, je l'ai testé à moitié et il semble être bon. Je vais avoir une chance de tester complètement bientôt et si cela fonctionne, je coche cette réponse. Merci! – Joe

+0

cela définit toujours chaque entrée d'année dans le résultat à 0, même s'il devrait y avoir une valeur là. – Joe

+1

@Joe Comment est-ce "réglage chaque entrée de l'année à 0"? Il y a clairement des 1 pour Franklin et Windham, comme pour mes résultats. Veuillez éditer votre question et fournir des données d'entrée et de sortie complètes et cohérentes. –

0

Je ne sais pas, je comprends ce que vous essayez d'atteindre, comme votre exemple d'entrée fait n ot correspond vraiment votre sortie, mais je pense que vous pouvez simplement utiliser une compréhension de la liste pour construire le résultat, vérifier si ces éléments sont dans les years, months et weeks listes, et en ajoutant un respectivement 1 ou 0:

>>> year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '3457', 1)) 
>>> month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 
>>> week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 
>>> [(x[0], x[1], int(x in year), int(x in month), int(x in week)) for x in set(year + week + month)] 
[('Chittendon', '3367', 0, 1, 1), 
('Windham', '3457', 1, 0, 0), 
('Fanklin Grand Isle', '5560', 1, 1, 1)] 

Si ces comptes peuvent effectivement être différents de 1, vous devez d'abord créer quelques dictionnaires cartographie les villes à leur année/mois/semaine compte, puis utilisez une compréhension de liste similaire comme ci-dessus respectifs:

>>> year_counts = {(name, code): count for (name, code, count) in year} 
>>> month_counts = {(name, code): count for (name, code, count) in month} 
>>> week_counts = {(name, code): count for (name, code, count) in week} 
>>> all_cities = [(name, code) for (name, code, count) in set(year + month + week)] 
>>> [(x[0], x[1], year_counts.get(x, 0), month_counts.get(x, 0), week_counts.get(x, 0)) for x in all_cities] 
[('Chittendon', '3367', 0, 1, 1), 
('Windham', '3457', 1, 0, 0), 
('Fanklin Grand Isle', '5560', 1, 1, 1)] 
+0

J'essaie de créer un rapport qui affichera un nombre d'appels entrants pour chaque emplacement, ventilé par année, mois à date et semaine à ce jour. Le problème est que ce sont trois appels db distincts, donc je dois fusionner tous ensemble et si un emplacement est manquant insérer le nom et 0s – Joe

+0

@Joe Cette question était claire, mais je suppose que ma première estimation n'a pas frappé le spot encore. Comment est-ce maintenant? Si ce n'est toujours pas ce que vous voulez, essayez de clarifier la question. –

+0

J'ai besoin que chaque résultat soit unique afin que je puisse envoyer le rapport par courrier électronique aux clients. Il devrait donc avoir le format 'name, code, yr count, month count, week count'. Où chacun de ceux-ci pourrait changer chaque semaine quand je cours le script – Joe