Merging python dictionaries differently - python-2.7

I've python dictionaries within a list as follows
[{"item1": {"item2": "300", "item3" : "10"}},
{"item2": { "item4": "90", "item5": "400" }},
{"item5": {"item6": "16"}},
{"item3": {"item8": "ava", "item1" : "xxx","item5": "400"}}]
And I want to construct a dictionary as follows
{
"item1" : {
"item2": "300",
"item4": "90",
"item5": "400",
"item6": "16",
"item3" : "10",
"item8": "ava"
}
Traversing method:
1) Starting with item1 => is a dict with two keys. Add it to the new dict.
2) Then take the first key in the first dict and check if there is any dictionary with this key. item2 is again a dict with two keys and hence add those keys to the new dict.
3) Repeat the same for the keys in item2 until nothing is there to traverse down. While traversing if there is already traversed dict found skip that. For eg, in the last dict item3, we have item5 which is already traversed and added to new dict. So we can skip traversing this key.
4) Repeat step 2, for second key in item1 (Has to be repeated depends upon the number of keys in first dict.)
I know this is more complex. Is there any possibility to achieve this?

Related

Python dictionary with tuples as key to new dictionary with keys as first element of tuple

I would like to convert the dictionary d1 to dictionary d2:
d1 = {('a','b'):1, ('a','c'):2, ('a','d'):3, ('b','c'):2, ('b','d'):1, ('c','f'):2, ('f','c'):2 }
d2 = {'a': [('b',1),('c',2) ,('d',3)], 'b':[('c',2),('d',1)], 'c':[('f',2)], 'f':[('c',2)]}
Can someone please tell me how to do this?
Just use for loop and loop through the dictionary, then make a new dictionary with your tuple first element as key
base = {('a','b'):1, ('a','c'):2, ('a','d'):3, ('b','c'):2, ('b','d'):1, ('c','f'):2, ('f','c'):2 }
newDict = {}
for key in base:
#Key is the tuple
if not key[0] in newDict.keys():
newDict[key[0]] = []
newDict[key[0]].insert(0, (key[1], base[key]))
print(newDict)
If you don't really care about the order of the list in new dictionary value, you should append instead of insert on 0 index, because insert on 0 index is slower than append.

Grabbing a dictionary given just a few keys and values

Suppose I have a list of dictionaries, all of which have the same keys. An instance of such a dictionary in the list might look like:
dict = {"Height": 6.0, "Weight": 201.5, "Name": "John", "Status": "Married"}
Given only a few (key, value) pairs, I want to extract all dictionaries satisfying those pairs. For example, if I have
attributes = {"Height": 5.5, "Name": "John"}
I want to extract all dictionaries whose height value is greater than or equal to 5.5 AND whose name value is John.
I'm able to write the code that can satisfy one OR the other, but dealing with mixed types (float and string) is throwing me off, so my AND operator is being confused I guess. The problem part of my code, for example, is:
for option in attributes.keys():
if dict[option] == attributes[option] and dict[option] >= attributes[option]
print dict
If you have multiple different condition you have to do all of them, but instead of using and you can use all built-in function and a function for filtering the dictionaries, then use it within a list comprehension or filter function in order to get the expected dictionaries.
from operator import itemgetter
option1, option2, option3 = itemgetter(key1, key2, key3)(attributes)
def filter_func(temp_dict):
# key1, key2, key3 have been defined already (keys in attributes)
val1, val2, val3 = itemgetter(key1, key2, key3)(temp_dict)
return all(option1 == val1, option2 => val2, option3 => val3)
filtered_result = filter(filter_func, list_of_dictionaries)
Also note that if it's possible that the dictionaries with your list don't have all the specified keys, the itemgetter might raise an KeyError for getting ride of that you can use dict.get attribute by passing a default value to it (based on your need).
For example for val3 you can use temp_dict.get(key3, 0).

dictionary: Unique relative values where values are of list type

I am getting the output of word2vec_basic.py in the following format
Nearest to key1 : node1, node2, node3 ..
Nearest to key2 : node2, node4, node5 ..
This implies that node2 is comparatively closer to key2 over key1 (Please correct me if I am wrong, as I am newbie here)
It would be great if I get the output in the following format
Nearest to key1 : node1, node3 , node6..
Nearest to key2 : node2, node4, node5 ..
That is, consider only the closest neighbor for clustering.
Suggestions for the same?
I am maintaining a python dictionary for the same of the following format:
{
key1: [node1,node2,node3],
key2: [node2,node4,node5]
}
But I required,
{
key1: [node1,node3,node6],
key2: [node2,node4,node5]
}
And for the above dictionary, I will be needing
Nearest to key1 : node1, node3 , node6..
Nearest to key2 : node2, node4, node5 ..
Could we do this in tensorflow itself, or should I define a function which takes dictionary as input and give me the required output?
For eg:
If we have a python dictionary of the following format:
{
a: ["abc","bcd","def"],
b: ["def","xyz"]
}
Here the values are list. I am looking for the following format from the above input:
{
a: ["abc","bcd"],
b: ["def","xyz"]
}
Suggestions are welcome on how I could achieve it.
Also, are there any python in built functions which could help me to reach the above output format?
dicts are unordered so which dupe gets removed is not guaranteed but you can keep a set of elements seen so far as you iterate over the items, updating/removing elements from the list/value if it has already been seen:
d = {
"a": ["abc","bcd","def"],
"b": ["def","xyz"]
}
seen = set()
for k,v in d.items():
d[k] = [seen.add(ele) or ele for ele in v if ele not in seen]
print(d)
This could output:
{'b': ['def', 'xyz'], 'a': ['abc', 'bcd']}
Or:
d = { "a": ["abc","bcd","def"], "b": ["xyz"]}
It completely depends on which key you hit first.
As you can see from this top answer with 436 upvotes, the removal logic is efficient and it maintains the order if required. To also to avoid the set.add lookup each time as in the link, you can set seen_add = seen.add and use seen._add(ele) in place of seen.add.
Since dictionaries entries in Python are unordered, you need to first build a separate dictionary keyed by node recording each list (or sequence) it's in as well as its index in that list so relative distances in each list can be compared to one another. After that's done, it can be referenced to determine whether each node should stay in each list it is in or not by making a second pass through the dictionary's contents.
d = {
"a": ["abc", "bcd", "def"],
"b": ["def", "xyz"]
}
def check_usage(k, elem_usage):
if len(elem_usage) == 1: # unique?
return True
else:
index = elem_usage[k] # within this elem's seq
for key,value in elem_usage.items():
if key != k:
if value < index:
return False
else:
return True
usage = {}
for key in d: # build usage dictionary
for index, item in enumerate(d[key]):
usage.setdefault(item, {})[key] = index
for k,seq in d.items():: # remove nodes that are closer in other lists
d[k] = [elem for elem in seq if check_usage(k, usage[elem])]
# display results
print('{')
for k in sorted(d):
print(' {!r}: {},'.format(k, d[k]))
print('}')
Output:
{
'a': ['abc', 'bcd'],
'b': ['def', 'xyz'],
}

Applescript: Merging lists into new lists

I am bumping up against what is probably an easy-fix problem as a relative Applescript noob. I have three lists of data which I want to re-organise. The first of the original lists contains ID numbers, the second names and the third a status. Example:
set listNumbers to {}
set listNumbers to {} & {4456, 3232, 6545, 789}
set listStatuses to {}
set listStatuses to {} & {"Eaten", "Beheaded", "Shot", "Lost"}
set listNames to {}
set listNames to {} & {"Jim", "Joe", "Steve", "Mike"}
I want to automatically extract / create x number of new lists, each with three items and following the pattern of item 1 from each list, item 2 from each list, etc. So I would get something like list1 = {4456, "Eaten", "Jim"}, list2 = {3232, "Beheaded", "Joe"}, etc. The original lists will actually be much longer, with several hundred items, and will be generated dynamically so I don't want to have manually code for every list.
I'm struggling to find useful examples to apply to this, but it seems like it should be straightforward! Any help much appreciated.
Try this, of course it assumes that all lists contain the same number of items.
The result is in the variable resultList
set listNumbers to {4456, 3232, 6545, 789}
set listStatuses to {"Eaten", "Beheaded", "Shot", "Lost"}
set listNames to {"Jim", "Joe", "Steve", "Mike"}
set resultList to {}
repeat with i from 1 to count listNumbers
set end of resultList to {item i of listNumbers, item i of listStatuses, item i of listNames}
end repeat
or you could get the result as a list of records {name:<name>, status:<status>, number:<number>}
...
repeat with i from 1 to count listNumbers
set end of resultList to {|number|:item i of listNumbers, status:item i of listStatuses, |name|:item i of listNames}
end repeat
I think the way you're suggesting, having hundreds of separate lists, is not going to be beneficial to you. I like to use "lists of lists". You would create is like so:
set listNumbers to {} & {4456, 3232, 6545, 789}
set listStatuses to {} & {"Eaten", "Beheaded", "Shot", "Lost"}
set listNames to {} & {"Jim", "Joe", "Steve", "Mike"}
set listOfLists to {}
repeat with n from 1 to (count listNumbers)
set end of listOfLists to {item n of listNumbers, item n of listStatuses, item n of listNames}
end repeat
return listOfLists
-- {{4456, "Eaten", "Jim"}, {3232, "Beheaded", "Joe"}, {6545, "Shot", "Steve"}, {789, "Lost", "Mike"}}
This way, you can reference item 2 of item 2 of listOfLists, etc.

How to add elements in a list, list consists a hashmap (key value pair) in groovy

I have added hashmap to a list
Here is my list which consists of three different hashmaps.
{504=1111.07, 502=969.64, 501=823.43, 503=680.2, 512=669.03, 505=647.0}
{504=235.18, 502=205.24, 501=174.29, 503=143.98, 512=141.61, 505=136.95}
{504=235.18, 502=205.24, 501=174.29, 503=143.98, 512=141.61, 505=136.95}
I want to add all values with key as 504
Ex: 1111.07+235.18+235.18
How can i do this?
def list = [
[504:1111.07, 502:969.64, 501:823.43, 503:680.2, 512:669.03, 505:647.0],
[504:235.18, 502:205.24, 501:174.29, 503:143.98, 512:141.61, 505:136.95],
[504:235.18, 502:205.24, 501:174.29, 503:143.98, 512:141.61, 505:136.95]
]
assert list.sum { it[504] } == 1581.43
should do.