Take a value from a nested list in Python - python
I ask for a value which is the id of the product.
The thing I want is the price of the product with that id, the last number.
Products code:
producto=[[0, "Patata", "PatataSL", 7], [1, "Jamon", "JamonSL", 21], [2, "Queso", "Quesito Riquito", 5], [3, "Leche", "Muu", 4], [4, "Oro", "Caro", 900], [5, "Zapatos", "Zapatito", 56], [6, "Falda", "Mucha ropa", 34]]
def productos():
respuesta=True
while respuesta:
print ("""
1.Mostrar Productos
2.Salir al menu
""")
respuesta=input("Introduzca la opcion ")
if respuesta=="1":
for r in producto:
for c in r:
print(c, end = " ")
print()
elif respuesta=="2":
import menu
elif respuesta !="":
print("\n No ha introducido un numero del menu")
Shopping code:
import clientes
import productos
def compras():
respuesta=True
while respuesta:
print ("""
1.Comprar
2.Salir al menu
""")
respuesta=input("Introduzca la opcion ")
if respuesta=="1":
i = int(input("Introduzca el id del cliente: "))
if i in (i[0] for i in clientes.cliente):
print("El cliente está en la lista")
else:
print("El cliente no está en la lista")
compras()
p = int(input("Introduzca el id del producto: "))
if p in (p[0] for p in productos.producto):
print("El producto esta en stock")
These are the things I´ve been trying but i get an error code: TypeError: 'int' object is not subscriptable.
for j in productos.producto:
for p in j:
print (str(p[3]))
#print("El producto cuesta: " + str(p[p][3]))
Last part is ok.
else:
print("El producto no esta en stock")
compras()
elif respuesta=="2":
import menu
elif respuesta !="":
print("\n No ha introducido un numero del menu")
you can get the nested item by simply adding an additional set of square brackets, so for 7 in the first nested list is producto[0][3]
You can grab the last element in a list by refering to it as the -1th element.
for productList in producto:
if respuesta == productList[0]:
print('Price:', productList[-1])
I assume that you need to print the price of the product based on the id.
producto=[[0, "Patata", "PatataSL", 7], [1, "Jamon", "JamonSL", 21], [2, "Queso", "Quesito Riquito", 5], [3, "Leche", "Muu", 4], [4, "Oro", "Caro", 900], [5, "Zapatos", "Zapatito", 56], [6, "Falda", "Mucha ropa", 34]]
I assume , index 0 is id and index 3 is Price.
product_id = 0 //user input
for v in producto:
if v[0] == product_id:
print(v[0][3])
you need to give the index of the price
If at all possible, it would be nice to see this type of structured data in a class or named tuple.
That way not only do you gain the benefit of always knowing what you're accessing. But it's very simple to figure out how to access it.
Consider the following code:
class Product():
def __init__(self, amount, name, something, price):
self.amount = amount
self.name = name
self.something = something
self.price = price
producto=[
Product(0, "Patata", "PatataSL", 7), Product(1, "Jamon", "JamonSL", 21),
Product(2, "Queso", "Quesito Riquito", 5), Product(3, "Leche", "Muu", 4),
Product(4, "Oro", "Caro", 900), Product(5, "Zapatos", "Zapatito", 56),
Product(6, "Falda", "Mucha ropa", 34)
]
print(producto[0].price)
It might look like more effort, but if you plan on making a large, even slightly complex program, using nested arrays and non-structured data you will find yourself constantly running into problems like the one your currently encountering.
That said, the answer is:
for j in productos.producto:
print (str(j[3]))
You went one level too deep into your nested array.
Related
Hey guys, I have a problem in my code, those *ELSE* and *PRINT* are with an issue, but I don't know what it is, can anyone help me?
import random print('\033[33m--------Jogo de Par ou Ímpar--------\033[m') r1 = input('Par ou Ímpar? '.lower().strip()) r2 = random.choice(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) resultado = 0 while True: if (r1 + r2) % 2 == 0: print('''O resultado foi Par sua jogada:{} jogada do computador{}'''.format(r1,r2)) resultado = 'par' if resultado == r1: print('\033[32mVocê VENCEU!\033[m') else: print('\033[31mVocê PERDEU, FIM DE JOGO\033[m') break print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-') *ELSE:* *PRINT*('''O resultado foi Ímpar sua jogada:{} jogada do computador{}'''.format(r1,r2)) if resultado == r1: print('\033[32mVocê VENCEU!\033[m') else: print('\033[31mVocê PERDEU, FIM DE JOGO\033[m') break print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-') also my pycharm shows 4 error messages Statement expected, found Py:ELSE_KEYWORD:18 Statement expected, found Py:COLON:18 Unexpected indent:19 Statement expected, found Py:DEDENT:27
Python | Modifying not Bound Objects still modifies both
I have a problem concerning copying object attributes, and making sure the attributes are not bound together I am implementing Data Tables in python, whose attributes are rows : list [ list ] column_names : list[str] I want to have a method that copy a table, to make modifications for instance, but I want it to be fully independent from the original table in order to have a non destructive approach def copy(self): print(Fore.YELLOW + "COPY FCN BEGINS" + Fore.WHITE) rows = list(self.rows) # FOR DEBUG PURPOSES pprint(rows) pprint(self.rows) print(f'{rows is self.rows}') names = list(self.column_names) # FOR DEBUG PURPOSES pprint(names) pprint(self.column_names) print(f'{names is self.column_names}') print(Fore.YELLOW + "COPY FCN ENDS" + Fore.WHITE) return Tableau( rows= rows, column_names= names ) Then I test it creating a table and copying it into another then i modify the new table and make sure it modified the latest only Problem : it modifies both however i made sure that the rows' list were not pointing to the same object so i am a bit confused here are the rsults result of copy function and here is the test function (using unittest) the test function : def test_copy(self): # on s'assure que les deux Tableaux sont bien identiques après la copie, mais différents si on en modifie l'un ( ils ne aprtagent pas la même liste en terme d adresse mémoire ) # on copie NewTable = self.TableauA.copy() self.assertEqual(NewTable.rows, self.TableauA.rows) self.assertEqual(NewTable.column_names, self.TableauA.column_names) print("Row B") pprint(self.rowB) print("New Table") print(NewTable) print("tableau A") print(self.TableauA) print( Fore.GREEN + "IS THE SAME OBJECT ?" + Fore.WHITE) print(f"{NewTable is self.TableauA}") print( Fore.GREEN + "ROWS IS THE SAME OBJECT ?" + Fore.WHITE) print(f"{NewTable.rows is self.TableauA.rows}") print( Fore.GREEN + "NAMES IS THE SAME OBJECT ?" + Fore.WHITE) print(f"{NewTable.column_names is self.TableauA.column_names}") # on modifie le nouveau Tableau NewTable.add_column(name="NewCol", column=self.rowB) print(Fore.YELLOW + "MODIFICATION" + Fore.WHITE) print(Fore.GREEN + "New Table" + Fore.WHITE) print(NewTable) print(Fore.GREEN + "tableau A" + Fore.WHITE) print(self.TableauA) # on s'assure qu'on a pas modifié les lignes dans les deux self.assertNotEqual(NewTable.rows, self.TableauA.rows) return and the results : results of the test function and finally : the add_column method def add_column(self, name : str, column : list, position : int =-1): n =len(self.rows) if position == -1 : position = n for k in range(n) : self.rows[k].insert(position, column[k]) self.column_names.insert(position, name) return Thank you !
I found it, in the end it was very subtle as a list of list the highest list in hierarchy : rows was indeed unique however the content of rows [the list that contains lists] was not : the observation lists were still tied even with the list() function here is how i made them unique rows = [ list( self.rows[k] ) for k in range( len(self.rows) ) ] here is the final code that wortks : def copy(self): rows = [ list( self.rows[k] ) for k in range( len(self.rows) ) ] names = list(self.column_names) return Tableau( rows= rows, column_names= names ) hope this will help others
What am i doing wrong there? error "index out of range" trying to fill a list with lists
I want to do a list with lists inside, with a for and i get index out of range I tryed with empleados.append() but it doesnt work def main(): empleados=[] for i in range(1): empleados[i][0](input("Ingrese el Nombre: ")) empleados[i][1](input("Ingrese el Apellido: ")) empleados[i][2](int(input("Ingrese el Sueldo Base: "))) empleados[i][3](int(input("Ingrese el AFP 1 o 2: "))) empleados[i][4](datetime(int(input("Ingrese la Fecha de Ingreso(pulsa intro cada vez 2000 12 31): ")),int(input("/")),int(input("/")))) empleados[i][5](int(input("Ingrese la cantidad de hijos que tiene: ")))
welcome to SO! There's no list at empleados[0] to insert new values into. I find something like this is a little easier to read: def main(): empleados=[] for i in range(1): empleado_nueva = [] empleado_nueva.append(input("Ingrese el Nombre: ")) empleado_nueva.append(input("Ingrese el Apellido: ")) empleado_nueva.append(int(input("Ingrese el Sueldo Base: "))) empleado_nueva.append(int(input("Ingrese el AFP 1 o 2: "))) empleado_nueva.append(datetime(int(input("Ingrese la Fecha de Ingreso(pulsa intro cada vez 2000 12 31): ")),int(input("/")),int(input("/")))) empleado_nueva.append(int(input("Ingrese la cantidad de hijos que tiene: "))) empleados.append(empleado_nueva) return empleados It's worth mentioning that the index-access pattern you're attempting (empleados[i][0] = ...) only works if there's something already at that index, for instance: >>> x = [] >>> x[0] = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list assignment index out of range >>> x = ['a', 'b', 'c'] >>> x[0] = 'd' >>> x ['d', 'b', 'c'] So the append's are probably the best way to go.
The problem is you're trying use empleados[i] as a list with an existing index you can insert into, when at the moment, it's not. You need to set up your variables a separate list and then append them. E.g. def main(): empleados=[] vars = [ input("Ingrese el Nombre: "), input("Ingrese el Apellido: "), int(input("Ingrese el Sueldo Base: ")), int(input("Ingrese el AFP 1 o 2: ")), datetime(int(input("Ingrese la Fecha de Ingreso(pulsa intro cada vez 2000 12 31): ")),int(input("/")),int(input("/"))), int(input("Ingrese la cantidad de hijos que tiene: ") empleados.append(vars)
I am trying to make a code to conjugate verbs in French, but I cannot change the keys ''je'' to ''j ' ''
I am trying to make my code work like this: Enter a verb in French: chanter Output 1: je chante tu chantes il ou elle chante nous chantons vous chantez ils ou elles chantent I succeeded in making the part above, but I cannot succeed in switching je to j' when the user enters, for instance: echapper Enter a verb in French: echapper Output 2: j'echappe tu echappes il ou elle echappe nous echappons vous echappez ils ou elles echappent Code: list = { "je": 'e', "tu": 'es', "il ou elle": 'e', "nous": 'ons', "vous": 'ez', "ils ou elles": 'ent' } veb = input("") for key in list: if veb.endswith('er'): b = veb[:-2] print(key, b + list[key]) I do not know how to change the key list['je'] to list['j''] to succeed with the Output 2.
If you use double quotes around j', i.e. "j'", it will work. Also, I recommend not using the name list for your dictionary because 1) it's a dictionary, not a list, and 2) you should avoid using builtin python names for your variables. Also, looks like that conjugation is treated differently, with "j'" at the beginning and "e" at the end (instead of "er"). dictionary = {"je":"j'","tu":'es',"il ou elle":'e',"nous": 'ons',"vous":'ez',"ils ou elles":'ent'} veb = input("") for key in dictionary: if veb.endswith('er'): b = veb[:-2] if key == 'je': print(key, dictionary[key] + b + 'e') else: print(key,b + dictionary[key])
You should just simply replace the print statement with an if statement: if key == "je" and (veb.startswith("a") or veb.startswith("e") or [etc.]): print("j'",b + list[key]) else: print(key,b + list[key])
Pandas + Python: More efficient code
This is my code: import pandas as pd import os import glob as g archivos = g.glob('C:\Users\Desktop\*.csv') for archiv in archivos: nombre = os.path.splitext(archiv)[0] df = pd.read_csv(archiv, sep=",") d = pd.to_datetime(df['DATA_LEITURA'], format="%Y%m%d") df['FECHA_LECTURA'] = d.dt.date del df['DATA_LEITURA'] df['CONSUMO']="" df['DIAS']="" df["SUMDIAS"]="" df["SUMCONS"]="" df["CONSANUAL"] = "" ordenado = df.sort_values(['NR_CPE','FECHA_LECTURA', 'HORA_LEITURA'], ascending=True) ##Agrupamos por el CPE agrupado = ordenado.groupby('NR_CPE') for name, group in agrupado: #Recorremos el grupo indice = group.index.values inicio = indice[0] fin = indice[-1] #Llenamos la primeras lectura de cada CPE, con esa lectura (porque no hay una lectura anterior) ordenado.CONSUMO.loc[inicio] = 0 ordenado.DIAS.loc[inicio] = 0 cont=0 for i in indice: #Recorremos lo que hay dentro de los grupos, dentro de los CPES(lecturas) if i > inicio and i <= fin : cont=cont+1 consumo = ordenado.VALOR_LEITURA[indice[cont]] - ordenado.VALOR_LEITURA[indice[cont-1]] dias = (ordenado.FECHA_LECTURA[indice[cont]] - ordenado.FECHA_LECTURA[indice[cont-1]]).days ordenado.CONSUMO.loc[i] = consumo ordenado.DIAS.loc[i] = dias # Hago las sumatorias, el resultado es un objeto DataFrame dias = agrupado['DIAS'].sum() consu = agrupado['CONSUMO'].sum() canu = (consu/dias) * 365 #Contador con el numero de courrencias de los campos A,B y C conta=0 contb=0 contc=0 #Como es un DF, para recorrerlo tengo que iterar sobre ellos para hacer la comparacion print "Grupos:" for ind, sumdias in dias.iteritems(): if sumdias <= 180: grupo = "A" conta=conta+1 elif sumdias > 180 and sumdias <= 365: grupo = "B" contb=contb+1 elif sumdias > 365: grupo = "C" contc=contc+1 print "grupo A: " , conta print "grupo B: " , contb print "grupo C: " , contc #Formateamos los campos para no mostrar todos los decimales Fdias = dias.map('{:.0f}'.format) Fcanu = canu.map('{:.2f}'.format) frames = [Fdias, consu, Fcanu] concat = pd.concat(frames,axis=1).replace(['inf','nan'],[0,0]) with open('C:\Users\Documents\RPE_PORTUGAL\Datos.csv','a') as f: concat.to_csv(f,header=False,columns=['CPE','DIAS','CONSUMO','CONSUMO_ANUAL']) try: ordenado.to_excel(nombre+'.xls', columns=["NOME_DISTRITO", "NR_CPE","MARCA_EQUIPAMENTO","NR_EQUIPAMENTO","VALOR_LEITURA","REGISTADOR","TIPO_REGISTADOR", "TIPO_DADOS_RECOLHIDOS","FACTOR_MULTIPLICATIVO_FINAL","NR_DIGITOS_INTEIRO","UNIDADE_MEDIDA", "TIPO_LEITURA","MOTIVO_LEITURA","ESTADO_LEITURA","HORA_LEITURA","FECHA_LECTURA","CONSUMO","DIAS"], index=False) print (archiv) print ("===============================================") print ("*****Se ha creado el archivo correctamente*****") print ("===============================================") except IOError: print ("===================================================") print ("¡¡¡¡¡Hubo un error en la escritura del archivo!!!!!") print ("===================================================") This takes a file where I have lectures of energy consumption from different dates for every light meter('NR_CPE') and do some calculations: Calculate the energy consumption for every 'NR_CPE' by substracting the previous reading with the next one and the result put in a new column named 'CONSUMO'. Calculate the number of days where I'v got a reading and sum up the number of days Add the consumption for every 'NR_CPE' and calculate the anual consumption. Finally I want to classify by number of days that every light meter('NR_CPE') has a lecture. A if it has less than 180 days, B between 180 and 1 year and C more than a year. And finally write this result in two differents files. Any idea of how should I re-code this to have the same output and be faster? Thank you all. BTW this is my dataset: ,NOME_DISTRITO,NR_CPE,MARCA_EQUIPAMENTO,NR_EQUIPAMENTO,VALOR_LEITURA,REGISTADOR,TIPO_REGISTADOR,TIPO_DADOS_RECOLHIDOS,FACTOR_MULTIPLICATIVO_FINAL,NR_DIGITOS_INTEIRO,UNIDADE_MEDIDA,TIPO_LEITURA,MOTIVO_LEITURA,ESTADO_LEITURA,DATA_LEITURA,HORA_LEITURA 0,GUARDA,A002000642VW,101,1865411,4834,001,S,1,1,4,kWh,1,1,A,20150629,205600 1,GUARDA,A002000642VW,101,1865411,4834,001,S,1,1,4,kWh,2,2,A,20160218,123300 2,GUARDA,A002000642VJ,122,204534,25083,001,S,1,1,5,kWh,1,1,A,20150629,205700 3,GUARDA,A002000642VJ,122,204534,27536,001,S,1,1,5,kWh,2,2,A,20160218,123200 4,GUARDA,A002000642HR,101,1383899,11734,001,S,1,1,5,kWh,1,1,A,20150629,205600 5,GUARDA,A002000642HR,101,1383899,11800,001,S,1,1,5,kWh,2,2,A,20160218,123000 6,GUARDA,A002000995VM,101,97706436,12158,001,S,1,1,5,kWh,1,3,A,20150713,155300 7,GUARDA,A002000995VM,101,97706436,12163,001,S,1,1,5,kWh,2,2,A,20160129,162300 8,GUARDA,A002000995VM,101,97706436,12163,001,S,1,1,5,kWh,2,2,A,20160202,195800 9,GUARDA,A2000995VM,101,97706436,12163,001,S,1,1,5,kWh,1,3,A,20160404,145200 10,GUARDA,A002000996LV,168,5011703276,3567,001,V,1,1,6,kWh,1,1,A,20150528,205900 11,GUARDA,A02000996LV,168,5011703276,3697,001,V,1,1,6,kWh,2,2,A,20150929,163500 12,GUARDA,A02000996LV,168,5011703276,1287,002,P,1,1,6,kWh,1,1,A,20150528,205900
Generally you want to avoid for loops in pandas. For example, the first loop where you calculate total consumption and days could be rewritten as a groupby apply something like: def last_minus_first(df): columns_of_interest = df[['VALOR_LEITURA', 'days']] diff = columns_of_interest.iloc[-1] - columns_of_interest.iloc[0] return diff df['date'] = pd.to_datetime(df['DATA_LEITURA'], format="%Y%m%d") df['days'] = (df['date'] - pd.datetime(1970,1,1)).dt.days # create days column df.groupby('NR_CPE').apply(last_minus_first) (btw I don't understand why you are subtracting each entry from the previous, surely for meter readings this is the same as last-first?) Then given the result of the above as consumption, you can replace your second for loop (for ind, sumdias in dias.iteritems()) with something like: pd.cut(consumption.days, [-1, 180, 365, np.inf], labels=['a', 'b', 'c']).value_counts()