is there any way to join dictionaries as a result in for loop.
Here is my sample code:
for value in data['actions']:
if 'remoteUrls' in value:
url = value['remoteUrls']
ref = value['lastBuiltRevision']['SHA1']
new_dict['url'] = url
new_dict['ref'] = ref
print new_dict
results:
{
'url': [u'ssh://abc.com:29418/abc.git'],
'ref': u'194d4c418c71f77355117bd253cf2ac9849b25dd'
}
{
'url': [u'ssh://def:29418/def.git'],
'ref': u'7a198bf01b73330c379cc54aae1631f4448a4b0b'
}
I want to join the results into one dictionary and the desired output is like this:
{
vcs1: {
'url': [u'ssh://abc.com:29418/abc.git'],
'ref': u'194d4c418c71f77355117bd253cf2ac9849b25dd'
},
vcs2: {
'url': [u'ssh://def:29418/def.git'],
'ref': u'7a198bf01b73330c379cc54aae1631f4448a4b0b'
}
}
Is there any way to achieve the desired output? Any help would be appreciated. Thank you.
This is one way:
lst = [{'url': [u'ssh://abc.com:29418/abc.git'],'ref':u'194d4c418c71f77355117bd253cf2ac9849b25dd'},
{'url': [u'ssh://def:29418/def.git'], 'ref': u'7a198bf01b73330c379cc54aae1631f4448a4b0b'}]
i = (i for i in range(len(lst)))
d = {'vcs{}'.format(next(i) + 1): x for x in lst}
print(d)
# {'vcs1': {'url': ['ssh://abc.com:29418/abc.git'], 'ref': '194d4c418c71f77355117bd253cf2ac9849b25dd'},
# 'vcs2': {'url': ['ssh://def:29418/def.git'], 'ref': '7a198bf01b73330c379cc54aae1631f4448a4b0b'}}
Or using itertools.count as suggested in comments:
from itertools import count
lst = [{'url':[u'ssh://abc.com:29418/abc.git'],'ref':u'194d4c418c71f77355117bd253cf2ac9849b25dd'},
{'url': [u'ssh://def:29418/def.git'], 'ref': u'7a198bf01b73330c379cc54aae1631f4448a4b0b'}]
i = count(1)
d = {'vcs{}'.format(next(i)): x for x in lst}
print(d)
# {'vcs1': {'url': ['ssh://abc.com:29418/abc.git'], 'ref': '194d4c418c71f77355117bd253cf2ac9849b25dd'},
# 'vcs2': {'url': ['ssh://def:29418/def.git'], 'ref': '7a198bf01b73330c379cc54aae1631f4448a4b0b'}}
Or this is even simple using enumerate:
d = {'vcs{}'.format(i): x for i, x in enumerate(lst, 1)}
There are some easy methods,
dict.update() will help you join dictionaries.
>>> a = dict()
>>> a.update({1:2})
>>> a
{1: 2}
>>> a.update({3:4})
>>> a
{1: 2, 3: 4}
dict['key'] = {'url':['URL'], 'ref':'REF'}
>>> a['key123'] = {'url':['url1','url2'], 'ref':'REF'}
>>> a
{1: 2, 'key1': {'a': 'hello'}, 3: 4, 'key123': {'url': ['url1', 'url2'], 'ref': 'REF'}, 'key2': {'url': ['URL1', 'URL2'], 'ref': u'ref'}}
As per your case,
res = dict()
for value in data['actions']:
if 'remoteUrls' in value:
res['key_name'] = {'url':value['remoteUrls'] ,
'ref':value['lastBuiltRevision']['SHA1']}
print res # check the entries
dict comprehension
dict(dict(<key>, {'url':value['remoteUrls'], 'ref':value['lastBuiltRevision']['SHA1']} for value in data['actions'] if 'remoteUrls' in value)
Related
I have a list:
List_ = ["Peter", "Peter", "Susan"]
I want to make a dictonary like this:
Dict_ = {"Name": "Peter", "Count": 2, "Name": "Susan", "Count": 1}
Dict_ = {}
Dict_new = {}
for text in List_:
if text not in Dict_:
Dict_[text] = 1
else:
Dict_[text] += 1
for key, values in Dict_.items():
Dict_new["Name"] = key
Dict_new["Count"] = values
print(Dict_new)
It is printing only last ones:
{"Name": "Susan", "Count": 1}
Here is the implementation that you can use according to what you would like :
from collections import Counter
# Your data
my_list = ["Peter", "Peter", "Susan"]
# Count the occurrences
counted = Counter(my_list)
# Your format
counted_list = []
for key, value in counted.items():
counted_list.append({"Name": key, "Count": value})
print(counted_list)
And output will be :
[{'Name': 'Peter', 'Count': 2}, {'Name': 'Susan', 'Count': 1}]
As noted in comments, a dictionary can only have each key once.
You may want a list of dictionaries, built with help from collections.Counter and a list comprehension.
>>> from collections import Counter
>>> List_ = ["Peter", "Peter", "Susan"]
>>> [{'name': k, 'count': v} for k, v in Counter(List_).items()]
[{'name': 'Peter', 'count': 2}, {'name': 'Susan', 'count': 1}]
In addition to using collections.Counter you could use a defaultdict.
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> for n in List_:
... d[n] += 1
...
>>> d
defaultdict(<class 'int'>, {'Peter': 2, 'Susan': 1})
>>> [{'name': k, 'count': v} for k, v in d.items()]
[{'name': 'Peter', 'count': 2}, {'name': 'Susan', 'count': 1}]
You can use the following code to achieve what you are trying to do.
List_ = ["Peter", "Peter", "Susan"]
dict_ = {}
for name in List_:
if name in dict_:
dict_[name] += 1
else:
dict_[name] = 1
print(dict_)
Generates the following output where key is the name and value is the count.
{'Peter': 2, 'Susan': 1}
Heres the original dict
uid_coins = {'141632864': {'username': 'Guest130679138', 'coins': 0},
'141632884': {'username': 'Guest130679156', 'coins': 39123441},
'141632886': {'username': 'Guest130679158', 'coins': 44006638}}
What I am trying to get
d = {'uid':[141632864, 141632884, 141632886],
'username': ['Guest130679138', 'Guest130679156', 'Guest130679158'],
'coins': [0, 39123441, 44006638]}
The keys in original dict represent uid.
This is my what I have done:
uid = list(uid_coins.keys())
username = [u_data['username'] for u_data in uid_coins.values()]
coins = [[u_data['coins'] for u_data in uid_coins.values()]]
d = {"uid":uid, "username":username, "coins":coins}
dict((key,d[key]) for d in data for key in d)
But I am rather looking for a generalized approach, to achieve without manually declaring the keys again, just so it should work with new keys in the original data.
Try:
uid_coins = {
"141632864": {"username": "Guest130679138", "coins": 0},
"141632884": {"username": "Guest130679156", "coins": 39123441},
"141632886": {"username": "Guest130679158", "coins": 44006638},
}
out = {}
for k, v in uid_coins.items():
out.setdefault("uid", []).append(k)
out.setdefault("username", []).append(v["username"])
out.setdefault("coins", []).append(v["coins"])
print(out)
Prints:
{'uid': ['141632864', '141632884', '141632886'],
'username': ['Guest130679138', 'Guest130679156', 'Guest130679158'],
'coins': [0, 39123441, 44006638]}
Generalized (based on original version by Andrej Kesely):
d = {}
for k, v in uid_coins.items():
d.setdefault('uid', []).append(k)
for i in v.keys():
d.setdefault(i, []).append(v[i])
A similar version as #Andrej Kesely but with defaultdict
from collections import defaultdict
uid_coins = {
'141632864': {'username': 'Guest130679138', 'coins': 0},
'141632884': {'username': 'Guest130679156', 'coins': 39123441},
'141632886': {'username': 'Guest130679158', 'coins': 44006638}
}
d = defaultdict(list)
for key, value in uid_coins.items():
d['uid'].append(key)
d['username'].append(value['username'])
d['coins'].append(value['coins'])
Output:
defaultdict(<class 'list'>, {'uid': ['141632864', '141632884', '141632886'], 'username': ['Guest130679138', 'Guest130679156', 'Guest130679158'], 'coins': [0, 39123441, 44006638]})
This is how you can get the output in desired format (as mentioned in question) from the given dictionary.
d = {'uid': list(uid_coins.keys()), 'username': [i['username'] for i in list(uid_coins.values())], 'coins': [i['coins'] for i in list(uid_coins.values())]}
list(uid_coins.keys()) will return all your uids as list.
[i['username'] for i in list(uid_coins.values())] will return 'username' values as list.
[i['coins'] for i in list(uid_coins.values())] will return 'coins' values as list.
I want to replace the values (formated as strings) with the same values as integers, whenever the key is 'current_values'.
d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}
Desired Output:
d = {'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}
The following piece of code replaces (substrings of) values in a dictionary. It works for nested json structures and copes with json, list and string types. You can easily add other types if needed.
def dict_replace_value(d: dict, old: str, new: str) -> dict:
x = {}
for k, v in d.items():
if isinstance(v, dict):
v = dict_replace_value(v, old, new)
elif isinstance(v, list):
v = list_replace_value(v, old, new)
elif isinstance(v, str):
v = v.replace(old, new)
x[k] = v
return x
def list_replace_value(l: list, old: str, new: str) -> list:
x = []
for e in l:
if isinstance(e, list):
e = list_replace_value(e, old, new)
elif isinstance(e, dict):
e = dict_replace_value(e, old, new)
elif isinstance(e, str):
e = e.replace(old, new)
x.append(e)
return x
# See input and output below
output = dict_replace_value(input, 'string', 'something')
Input:
input = {
'key1': 'a string',
'key2': 'another string',
'key3': [
'a string',
'another string',
[1, 2, 3],
{
'key1': 'a string',
'key2': 'another string'
}
],
'key4': {
'key1': 'a string',
'key2': 'another string',
'key3': [
'a string',
'another string',
500,
1000
]
},
'key5': {
'key1': [
{
'key1': 'a string'
}
]
}
}
Output:
print(output)
{
"key1":"a something",
"key2":"another something",
"key3":[
"a something",
"another something",
[
1,
2,
3
],
{
"key1":"a something",
"key2":"another something"
}
],
"key4":{
"key1":"a something",
"key2":"another something",
"key3":[
"a something",
"another something",
500,
1000
]
},
"key5":{
"key1":[
{
"key1":"a something"
}
]
}
}
d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}
for elem in d['datastreams']: # for each elem in the list datastreams
for k,v in elem.items(): # for key,val in the elem of the list
if 'current_value' in k: # if current_value is in the key
elem[k] = int(v) # Cast it to int
print(d)
OUTPUT:
{'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}
A general approach (assuming you don't know in advance which key of the dict is pointing to a list) would be to iterate over the dict and check the type of its values and then iterate again into each value if needed.
In your case, your dictionary may contain a list of dictionaries as values, so it is enough to check if a value is of type list, if so, iterate over the list and change the dicts you need.
It can be done recursively with a function like the following:
def f(d):
for k,v in d.items():
if k == 'current_value':
d[k] = int(v)
elif type(v) is list:
for item in v:
if type(item) is dict:
f(item)
>>> d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}
>>> f(d)
>>> d
{'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}
Can be done with list comprehension:
d['datastreams'] = [{'current_value': int(ds['current_value'])} if ('current_value' in ds) else ds for ds in d['datastreams']]
You can use ast.literal_eval to evaluate the underlying value for items with current_value key in the d['datastreams'] list. Then check whether the type is an int using isinstance for such values. Finally, type cast such values to int.
import ast
d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}
for i in d['datastreams']:
for k,v in i.items():
if 'current_value' in k and isinstance(ast.literal_eval(v),int):
i[k] = int(v)
#Output:
print(d)
{'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}
You could use this method
which would loop through checks for current_value in list and change it to integer by passing the value through int() function:
for value in d.values():
for element in value:
if 'current_value' in element:
element['current_value'] = int(element['current_value'])
Taking alec_djinn's solution little farther to handle also nested dicts:
def f(d):
for k,v in d.items():
if k == 'current_value':
d[k] = int(v)
elif type(v) is list:
for item in v:
if type(item) is dict:
f(item)
if type(v) is dict:
f(v)
I have the following function:
def count_chars(e):
return len(e)
I am iterating a json as follows:
In:
a_lis = []
with open('../JSON_FILE.json','r') as fa:
a = json.load(fa)
for e in a['entries']:
pprint(e)
Out:
{'data': ['string'], 'type': 'one'}
{'data': ['a string '], 'type': 'one'}
{'data': ['another string'], 'type': 'three'}
...
{'data': ['one more string'], 'type': 'two'}
How can I apply count_chars function and add it or update it as a new string in the 'data' list? For instance the expected output would look like:
{'data': ['string','6'], 'type': 'one'}
{'data': ['a string','8'], 'type': 'one'}
{'data': ['another string','14'], 'type': 'three'}
...
{'data': ['one more string','15'], 'type': 'two'}
UPDATE:
I found that my lists have more than one item, for example: ['first', 'second string']? How can I return ['first', len_1, 'second string', len_2]
You could use append():
lst = [
{"data": ["string"], "type": "one"},
{"data": ["a string "], "type": "one"},
{"data": ["another string"], "type": "three"},
]
def count_chars(e):
return len(e)
for d in lst:
d["data"].append(count_chars(d["data"][0]))
print(lst)
# [{'data': ['string', 6], 'type': 'one'}, {'data': ['a string ', 9], 'type': 'one'}, {'data': ['another string', 14], 'type': 'three'}]
If you have more strings in the list, you can use extend() and rebuild a new list:
lst = [
{"data": ["string", "hi"], "type": "one"},
{"data": ["a string "], "type": "one"},
{"data": ["another string"], "type": "three"},
]
def count_chars(e):
return len(e)
for d in lst:
newlst = []
for x in d["data"]:
newlst.extend([x, count_chars(x)])
d["data"] = newlst
print(lst)
# [{'data': ['string', 6, 'hi', 2], 'type': 'one'}, {'data': ['a string ', 9], 'type': 'one'}, {'data': ['another string', 14], 'type': 'three'}]
Note: Since count_chars() simply returns len(), it might be easier to just call len() itself.
That should work :)
def count_chars(e):
return len(e)
a_lis = []
with open('../JSON_FILE.json','r') as fa:
a = json.load(fa)
for e in a['entries']:
for String in e["data"]: # Grab one string inside the strings list.
if type(String) == int:
continue # Skip the count chars value that you appended.
Length = count_chars(String) # Apply the function.
e["data"].append(Length) # Append the returned value to the data list containing the string.
# Now we reorder the list from ["a", "ab", "abc", 1, 2, 3] to ["a", 1, "ab", 2, "abc", 3]
strings_found = int(len(e["data"])/2)
reordered_list = []
for start in range(0, strings):
reordered_list = reordered_list + [x for x in e["data"][start::strings_found ]]
e["data"] = reordered_list
I have JSON dictionary something like this:
{'foo': 3, 'bar': 1}
and i want it in JSON array form:
[ { "key": "foo", "value": 3 }, { "key": "bar", "value": 1 }]
What should I do?
You need to iterate over keys and values for this dictionary and then assign the necessary keys in the new dictionary.
import json
input_dict = {'foo': 3, 'bar': 1}
result = []
for k, v in input_dict.items():
result.append({'key': k, 'value': v})
print(json.dumps(result))
And the result:
[{'value': 3, 'key': 'foo'}, {'value': 1, 'key': 'bar'}]
This could be handled with a list comprehension:
import json
json_dict = {'foo': 3, 'bar': 1}
json_array = [ {'key' : k, 'value' : json_dict[k]} for k in json_dict]
print(json.dumps(json_array))
output:
[{"key": "foo", "value": 3}, {"key": "bar", "value": 1}]
Try this (Python 2.7 and above):
json_dict = {'foo': 3, 'bar': 1} # your original dictionary;
json_array = [] # an array to store key-value pairs;
# Loop through the keys and values of the original dictionary:
for key, value in json_dict.items():
# Append a new dictionaty separating keys and values from the original dictionary to the array:
json_array.append({'key': key, 'value': value})
One-liner that does the same thing:
json_array = [{'key': key, 'value': value} for key, value in {'foo': 3, 'bar': 1}.items()]
Hope this helps!