Combining two lists into dictionary - python

I'm having issues trying to combine two lists that I have, Username and Account into a dictionary(username being the key and account being the value). My issue is I want any value with the same key to be added together(i.e the Brandon would only show up once with a value of 115.5). I would also like to skip the key/value pair for any blank or non-number values. Any help would be appreciated.
username = ['Brandon', 'Patrick', 'Brandon', 'Jack', '', 'Sarah', 'Jack', 'Brandon', 'James', 'James', 'Sarah', '', 'Brandon']
account = ['5', '18.9', 'xyz', '', '', '825', '45', '10', '3.25', '125.62', '2.43', '', '100.5']

You can zip together corresponding elements. Skip invalid values by catching errors on conversion to float, and use the falsiness of empty strings to skip empty keys
names = {}
for k, v in zip(username, account):
# check for empty keys
if not k:
continue
# an error on float conversion is due to a non
# numeric string (float or int)
try:
v = float(v)
except:
continue
# if the key is not in names, then .get will return
# 0, otherwise the last value set
names[k] = names.get(k, 0) + v
names
{'Brandon': 115.5, 'Patrick': 18.9, 'Sarah': 827.43, 'Jack': 45.0, 'James': 128.87}

How about this?
The more advanced things you may want to look up are: defaultdict and zip
from collections import defaultdict
username = ['Brandon', 'Patrick', 'Brandon', 'Jack', '', 'Sarah', 'Jack', 'Brandon', 'James', 'James', 'Sarah', '', 'Brandon']
account = ['5', '18.9', 'xyz', '', '', '825', '45', '10', '3.25', '125.62', '2.43', '', '100.5']
result = defaultdict(list)
for u, a in zip(username, account):
if a != '':
result[u].append(a)

You can use zip. all with check the conditions if not '' and value is not numeric.
from collections import defaultdict
d = defaultdict(float)
for i in zip(username, account):
if all([*i, i[1].replace('.','').isdigit()]):
d[i[0]] += float(i[1])
{'Brandon': 115.5,
'Patrick': 18.9,
'Sarah': 827.43,
'Jack': 45.0,
'James': 128.87}

from collections import defaultdict
def isfloat(value):
try:
float(value)
return True
except ValueError:
return False
username = ['Brandon', 'Patrick', 'Brandon', 'Jack', '', 'Sarah', 'Jack', 'Brandon', 'James', 'James', 'Sarah', '', 'Brandon']
account = ['5', '18.9', 'xyz', '', '', '825', '45', '10', '3.25', '125.62', '2.43', '', '100.5']
result = {}
for u, a in zip(username, account):
if isfloat(a):
if u not in result.keys():
result[u] = float(a)
else:
result[u] += float(a)

This will help, try part will automatically skip any non-digit values
username = ['Brandon', 'Patrick', 'Brandon', 'Jack', '', 'Sarah', 'Jack', 'Brandon', 'James', 'James', 'Sarah', '', 'Brandon']
account = ['5', '18.9', 'xyz', '', '', '825', '45', '10', '3.25', '125.62', '2.43', '', '100.5']
new_dict = {}
for key, value in zip(username, account):
try:
new_dict[key]=new_dict.get(key, 0.0) + float(value)
except:
pass
print(new_dict)

Related

Convert list of key/value pairs to nested dictionary

Input data:
data = [
['QR', ''],
['Cust', ''],
['fea', 'restroom'],
['chain', 'pa'],
['store', 'cd'],
['App', ''],
['End', 'EndnR'],
['Request', '0'],
['Sound', '15'],
['Target', '60'],
['Is', 'TRUE']
]
I want to turn this into a dictionary, and each blank value indicates the start of a new, nested sub-dictionary.
Desired output:
{
'QR': {
'Cust': {
'fea': 'restroom ',
'chain': 'pa',
'store': 'cd'
},
'App': {
'End': 'EndnR',
'Request': '0',
'Sound': '15',
'Target': '60',
'Is': 'true'
},
}
}
Here is my code so far:
from collections import defaultdict
res = defaultdict(dict)
for i in data:
res[i[0]] = i[1]
print(res)
But it only creates a flat dictionary with some blank values, not a nested dictionary.
try this:
result = {}
nbr_keys = 0
keys = [ item[0] for item in data if item[1] == "" ]
for index, item in enumerate(data):
if index == 0:
if item[1] == "":
key = item[0]
di[item[0]] = {}
else:
if item[1] == "":
di[key].update({item[0]: {}})
nbr_keys +=1
else:
di[key][keys[nbr_keys]].update({item[0]: item[1]})
which outputs this:
{'QR': {'Cust': {'fea': 'restroom', 'chain': 'pa', 'store': 'cd'},
'App': {'End': 'EndnR',
'Request': '0',
'Sound': '15',
'Target': '60',
'Is': 'TRUE'}}}

Convert list of dictionaries with different keys to values string list

Example list of dicts:
[{'name': 'aly', 'age': '104'}, {'name': 'Not A name', 'age': '99'}]
Expected out = ['aly', '104', 'Not A name', '99']
Any help will be much appreciated.
Thanks!
Try this in one line:
d = [{'name': 'aly', 'age': '104'}, {'name': 'Not A name', 'age': '99'}]
[v for i in d for k,v in i.items()]
The result will be:
Out[1]: ['aly', '104', 'Not A name', '99']
Another way :
listDictionary = [{'name': 'aly', 'age': '104'}, {'name': 'Not A name', 'age': '99'}]
out = []
for i in listDictionary:
for k, v in i.items():
out.append(v)
print(out)
Output : ['aly', '104', 'Not A name', '99']

How to select from two lists with two matching object atributes?

I have two lists of objects and I need to select the items that have the same attribute cpf and value:
This is my object class:
class Clientes:
def __init__(self):
self.nome = ""
self.cpf = ""
self.valor = ""
self.proposta = ""
And this my main code:
from objetos import Clientes
ArquivoA = {'Cliente1': ['Antonio', '123', '150', 'a'],
'Cliente2': ['Betina', '456', '200', 'b'],
'Cliente3': ['Dagmar', '789', '300', 'c'],
'Cliente4': ['Richard', '001', '400', 'd'],
'Cliente5': ['Maria', '435', '80', 'e']}
ArquivoB = {'Cliente1': ['Antonio', '123', '150'],
'Cliente2': ['Betina', '456', '200'],
'Cliente3': ['Dagmar', '789', '250'],
'Cliente4': ['Richard', '001', '450'],
'Cliente5': ['Jose', '987', '500']}
listaA= []
listaB = []
for item in ArquivoA:
c = Clientes()
c.nome = ArquivoA[item][0]
c.CPF = ArquivoA[item][1]
c.valor = ArquivoA[item][2]
c.proposta = ArquivoA[item][3]
listaA.append(c)
print(listaA)
for item in ArquivoB:
b = Clientes()
b.nome = ArquivoB[item][0]
b.CPF = ArquivoB[item][1]
b.valor = ArquivoB[item][2]
listaB.append(c)
print(listaB)
I want to create a new list where c.CPF == b.CPF and c.value == b.value. I don't want to use double loop for this, because my real list is so big.
Build dictionaries by your attributes of interest using dict comprehensions.
Find common keys using set intersections.
Now go and grab the values stored in the lookup dictionaries.
ArquivoA = {'Cliente1': ['Antonio', '123', '150', 'a'],
'Cliente2': ['Betina', '456', '200', 'b'],
'Cliente3': ['Dagmar', '789', '300', 'c'],
'Cliente4': ['Richard', '001', '400', 'd'],
'Cliente5': ['Maria', '435', '80', 'e']}
ArquivoB = {'Cliente1': ['Antonio', '123', '150'],
'Cliente2': ['Betina', '456', '200'],
'Cliente3': ['Dagmar', '789', '250'],
'Cliente4': ['Richard', '001', '450'],
'Cliente5': ['Jose', '987', '500']}
class Clientes:
def __init__(self, nome, CPF, valor, proposta=None):
self.nome = nome
self.CPF = CPF
self.valor = valor
self.proposta = proposta
def __repr__(self) -> str:
return f"{self.__dict__}"
list_a = [Clientes(v[0], v[1], v[2],v[3]) for v in ArquivoA.values()]
list_b = [Clientes(v[0], v[1], v[2]) for v in ArquivoB.values()]
#build a lookup dictionary by CPF, valor
di_a = {(c.CPF, c.valor) : c for c in list_a}
di_b = {(c.CPF, c.valor) : c for c in list_b}
#use sets to find common keys
set_a = set(di_a.keys())
set_b = set(di_b.keys())
common = set_a & set_b
#compare or do something else with the matching instances
for key in common:
va = di_a[key]
vb = di_b[key]
print(f"\n\n{key}:\n {va=}\n {vb=}" )
output:
('123', '150'):
va={'nome': 'Antonio', 'CPF': '123', 'valor': '150', 'proposta': 'a'}
vb={'nome': 'Antonio', 'CPF': '123', 'valor': '150', 'proposta': None}
('456', '200'):
va={'nome': 'Betina', 'CPF': '456', 'valor': '200', 'proposta': 'b'}
vb={'nome': 'Betina', 'CPF': '456', 'valor': '200', 'proposta': None}

How to get lenght of dict keys after specific element?

There is a dict
example_dict =
{'spend': '3.91',
'impressions': '791',
'clicks': '19',
'campaign_id': '1111',
'date_start': '2017-11-01',
'date_stop': '2019-11-27',
'age': '18-24',
'gender': 'male'}
I have to check if there are any additional keys after date_stop key and if yes, get the lenght of them and their names.
So far I made a list of keys
list_keys = list(example_dict.keys())
list_keys =
['spend',
'impressions',
'clicks',
'campaign_id',
'date_start',
'date_stop',
'age',
'gender']
And to check that there is 'date_stop' element is simple
if 'date_stop' in list_keys:
# what next
But how to proceed am not sure. Appreciate any help.
I guess it should be implement in diffrent way, You should be using dict, but if You really want to do this way You could use OrderedDict from collections:
from collections import OrderedDict
my_dict = {
'spend': '3.91',
'impressions': '791',
'clicks': '19',
'campaign_id': '1111',
'date_start': '2017-11-01',
'date_stop': '2019-11-27',
'age': '18-24',
'gender': 'male'
}
sorted_ordered_dict = OrderedDict(sorted(my_dict.items(), key=lambda t: t[0]))
if 'date_stop' in sorted_ordered_dict.keys():
keys = list(sorted_ordered_dict.keys())
index = keys.index('date_stop')
after_list = keys[index:]
print('len: ', len(after_list))
print('list: ', after_list)
use below code:
new_dict={}
list_keys = list(example_dict.keys())
k=""
for i in list_keys:
if 'date_stop' == i:
k="done"
if k=="done":
new_dict[i]=len(i)
output:
{'date_stop': 9, 'age': 3, 'gender': 6}
I hope you understand your question
if you want just name and number of keys use this:
new_dict=[]
list_keys = list(example_dict.keys())
k=""
for i in list_keys:
if 'date_stop' == i:
k="done"
if k=="done":
new_dict.append(i)
output:
print (new_dict)
print (len(new_dict))
['date_stop', 'age', 'gender']
3

Create dict from string in Python

In my Python program, I have a string of format:
'name': 'Salman','age': '25', 'access': 'R', 'id': '00125'
I want to convert it to type dict so that I can query like dict["name"] to get "Salman" printed.
Use ast.literal_eval:
import ast
mystr = "'name': 'Salman','age': '25', 'access': 'R', 'id': '00125'"
d = ast.literal_eval('{'+mystr+'}')
# {'access': 'R', 'age': '25', 'id': '00125', 'name': 'Salman'}
d['access'] # 'R'
I think this is a neat solution using comprehensions
s = "'name': 'Salman','age': '25', 'access': 'R', 'id': '00125'"
d = dict([i.strip().replace("'", "") for i in kv.split(':')] for kv in s.split(","))
# d == {'access': 'R', 'age': '25', 'id': '00125', 'name': 'Salman'}
first split the string by ":" and "," and store it in a list.
then iterate from 0 to len(list)-2: mydict[list[i]] = list[i+1]

Categories