Problem while loop with Python sum

0

from the following data:

restaurantes = [('Burger King', 'MA', 'Chicopee', '1284 Memorial Dr', '1020', '42.1927', '-72.5763'), ("Taco Bell", 'MA', 'Chicopee', '1606 Memorial Dr', '1020', '42.201117596', '-72.574102772'), ('Pizza Hut', 'MA', 'Easthampton', '113 Northampton St', '1027', '42.278666', '-72.671148'), ("Jack in the Box", 'MA', 'Holyoke', '285 Maple St', '1040', '42.20578', '-72.61053')]

I have managed to do the following function that returns the percentage of "x" restaurant brand in the restaurants variable:

def porcentaje_burger_king(restaurante, name):
    nombres = [nombre for nombre, _, _, _, _, _, _ in restaurantes if nombre == name]
    result = (len(nombres)/len(restaurantes))*100
    return result

Which runs with:

print(porcentaje(restaurantes, "Burger King")) #(0.25)

The problem is that I can not create a function that returns the percentage of each brand that is in the restaurants variable. I have tried with the following function, which gives wrong data:

def porcentajes_por_nombres(restaurantes):
    nombres = [nombre for nombre, _, _, _, _, _, _ in restaurantes]
    porcentajes = []
    indice = 0
    while indice < len(nombres):
        porcentaje_x = (len(nombres[indice])/len(restaurantes))*100
        porcentajes.append(porcentaje_x)
        indice +=1
    return porcentajes

print(porcentajes_por_nombres(restaurantes)) #Devuelve [275.0, 225.0, 225.0, 375.0] en vez de [0.25, 0.25, 0.25, 0.25]

I need the result in the form of a list, so I can use the zip function with the variables names and percentages, thanks in advance.

    
asked by Jesus_jbs 10.11.2018 в 13:06
source

1 answer

3

Unpack the tuple to extract the name, but the rest of the elements do not interest you and that's why you use _ . Consider not unpacking and using an index to collect the first element, like this:

nombres = [r[0] for r in restaurantes if r[0] == name]

Naturally that will give you repeated names, which is fine for the function that wants to count how many times each name appears, because len(nombres) gives you that data. But for the other function in which you simply need to collect all the names, you do not want them to appear repeated. So you could use a set:

nombres = set(r[0] for r in restaurantes)

Then you could go through that set and use the other function, to calculate the percentage. You can save the tuples (name, percentage) in a list to directly return that list and not have to do zip() . For example:

def porcentaje_restaurante(restaurantes, name):
    nombres = [r[0] for r in restaurantes if r[0] == name]
    result = (len(nombres)/len(restaurantes))*100
    return result

def porcentajes_por_nombres(restaurantes):
    nombres = set(r[0] for r in restaurantes)
    resultado = []
    for nombre in nombres:
      resultado.append((nombre, porcentaje_restaurante(restaurantes, nombre)))
    return resultado

porcentajes_por_nombres(restaurantes)

Alternative

An even simpler and shorter way is to make use of the standard module collections , which has a class Counter() that serves precisely to count the times that an element is repeated within an iterable one.

We can use it to count the names of the restaurants:

import collections
contador = collections.Counter(r[0] for r in restaurantes)

The result of the account is a dictionary in which each key is a different element (restaurant name) and the value is an integer with the number of times it has appeared repeated. From that it is trivial to create your list of (name, percentage):

import collections
resultado = []
total = len(restaurantes)
contador = collections.Counter(r[0] for r in restaurantes)
for nombre, veces in contador.items():
  resultado.append((nombre, veces/total*100))

Result:

[('Burger King', 25.0),
 ('Taco Bell', 25.0),
 ('Pizza Hut', 25.0),
 ('Jack in the Box', 25.0)]
    
answered by 10.11.2018 / 14:05
source