I am working on social media mutual friend problem and I choose to represent them using a dictionary. I am stuck at the part where you take a pair of users say a and b and create a set having union of their friend lists, something like
ab -> [{b,c,d,e},{c,d,a}]
NOTE: the code below says there is a user and he has some friends which are stored in a dictionary.
Now I want to pair each user with every other user in their friend list and create a list of sets which will have friend lists of both the users.
users = {
'a': ['b', 'c', 'd', 'e'],
'b': ['c', 'd', 'a'],
'c': ['a', 'b'],
'd': ['a','b','e'],
'e': ['a','d']
}
You can convert the dict of lists to a dict of sets, so that you can use set intersection for each combination of two users returned by itertools.combinations to find their mutual friends, and form a dict of sets indexed by frozensets of user pairs:
from itertools import combinations
u = {k: set(l) for k, l in users.items()}
{frozenset((a, b)): u[a] & u[b] for a, b in combinations(u, 2)}
This returns:
{frozenset({'b', 'a'}): {'c', 'd'},
frozenset({'a', 'c'}): {'b'},
frozenset({'a', 'd'}): {'b', 'e'},
frozenset({'a', 'e'}): {'d'},
frozenset({'b', 'c'}): {'a'},
frozenset({'b', 'd'}): {'a'},
frozenset({'b', 'e'}): {'a', 'd'},
frozenset({'c', 'd'}): {'b', 'a'},
frozenset({'c', 'e'}): {'a'},
frozenset({'e', 'd'}): {'a'}}
Related
I have a list like this:
original_list= ['A', 'B', 'C', 'D', 'E']
How would I be able to write a function to convert it into this:
converted_list= [{'A': 1}, {'B': 1}, {'C': 1}, {'D': 1}, {'E': 1}]
All the values in each dictionary are 1.
Thank you!
Use a list comprehension:
converted_list = [{s: 1} for s in original_list]
I have a dataframe (but it also can be just sets/lists):
Group Letter
1 {a,b,c,d,e}
2 {b,c,d,e,f}
3 {b,c,d,f,g}
4 {a,b,c,f,g}
5 {a,c,d,e,h}
I want to add column with intersection of group 1-2, 1-2-3, 1-2-3-4, 1-2-3-4-5.
So it'll be sth like this:
Group Letter Intersection
1 {a,b,c,d,e} None
2 {b,c,d,e,f} {b,c,d,e}
3 {b,c,d,f,g} {b,c,d}
4 {a,b,c,f,g} {b,c}
5 {a,c,d,e,h} {c}
I've read abt np.intersect1d, set.intersection, so I can do an intersection of multiple sets.
But I don't know how to do it in smart way.
Can someone help me with this problem?
You might itertools.accumulate for this task as follows
import itertools
letters = [{"a","b","c","d","e"},{"b","c","d","e","f"},{"b","c","d","f","g"},{"a","b","c","f","g"},{"a","c","d","e","h"}]
intersections = list(itertools.accumulate(letters, set.intersection))
print(intersections)
output
[{'e', 'a', 'b', 'c', 'd'}, {'b', 'e', 'c', 'd'}, {'b', 'c', 'd'}, {'b', 'c'}, {'c'}]
Note first element is {'e', 'a', 'b', 'c', 'd'} rather than None, so you would need to alter intersections in that regard.
I have a dictionary wherein the key is a unique name and the value is a list of non-unique names.
For domain knowledge sake, the keys are Tableau workbooks and the value is a list of tables the workbook connects to.
What I am trying to do is return, for each key, every other key that has at least three matching values. Doing so will basically allow me to find workbooks that are overlapping data by using the same tables.
Currently, I am able to find all keys that match a specific value by doing the following:
keys = [key for key, value in intersect_dict.items() if 'VOLUME_DIMENSION' in value]
keys
values = [value for key, value in intersect_dict.items() if 'VOLUME_DIMENSION' in value]
values
The output of keys is:
['(SAN) STORAGE GROUP INVENTORY AND CAPACITY',
'(SAN) STORAGE GROUP INVENTORY AND CAPACITY V2',
'SAN INVENTORY AND CAPACITY']
And the output of values is:
[['VOLUME_DIMENSION',
'EXTENDED_DATA',
'VOLUME_HISTORY_CAPACITY_FACT',
'HOST_DIMENSION',
'STORAGE_DIMENSION',
'DATE_DIMENSION'],
['STORAGE_DIMENSION',
'DATE_DIMENSION',
'VOLUME_DIMENSION',
'HOST_DIMENSION',
'VOLUME_HISTORY_CAPACITY_FACT',
'EXTENDED_DATA'],
['VOLUME_HISTORY_CAPACITY_FACT',
'HOST_DIMENSION',
'EXTENDED_DATA',
'DATE_DIMENSION',
'STORAGE_DIMENSION',
'VOLUME_DIMENSION']]
Is there a possible way that I can do essentially the same thing except instead of
if 'VOLUME_DIMENSION' in value I have if values in value match 3 times or more?
Please let me know if more info is needed.
Edit1: Below is the input dictionary excerpt requested:
{'(SAN) STORAGE GROUP INVENTORY AND CAPACITY': ['VOLUME_DIMENSION',
'EXTENDED_DATA',
'VOLUME_HISTORY_CAPACITY_FACT',
'HOST_DIMENSION',
'STORAGE_DIMENSION',
'DATE_DIMENSION'],
'(SAN) STORAGE GROUP INVENTORY AND CAPACITY V2': ['STORAGE_DIMENSION',
'DATE_DIMENSION',
'VOLUME_DIMENSION',
'HOST_DIMENSION',
'VOLUME_HISTORY_CAPACITY_FACT',
'EXTENDED_DATA'],
The requested output would be something like:
{'(SAN) STORAGE GROUP INVENTORY AND CAPACITY': workbook1, workbook7, workbook8}
The "workbooks" shown as values would be the workbooks who have three or more matching values with that key.
Edit2: Sorry for bad data format explanation. Attempting to clarify that here.
d = {
'item1': ['A', 'B', 'C'],
'item2': ['A', 'B', 'C', 'D'],
'item3': ['A', 'C', 'D'],
'item4': ['B', 'C', 'D', 'E'],
'item5': ['A', 'B', 'C'],
'item6': ['A', 'B', 'C', 'E'],
}
Results = {
'item1': ['item2', 'item5', 'item6']
'item2': ['item1', 'item5', 'item6']
}
In the above example, d would be my overall dataset in dictionary form and Results are what I would like for the output to be. So it would let me target which items are sharing data. Or in this case, sharing letters.
I would use set:
d = {
'item1': ['A', 'B', 'C'],
'item2': ['A', 'B', 'C', 'D'],
'item3': ['A', 'C', 'D'],
'item4': ['B', 'C', 'D', 'E'],
}
search_items = {'A', 'B', 'C'}
keys = [key for key, value in d.items() if len(search_items & set(value)) >= 3]
print(keys)
values = [value for key, value in d.items() if len(search_items & set(value)) >= 3]
print(values)
Output:
['item1', 'item2']
[['A', 'B', 'C'], ['A', 'B', 'C', 'D']]
To get all keys that share three or more items, you can do:
common_items = [
(search_key, key, set(search_values) & set(values))
for search_key, search_values in d.items()
for key, values in d.items()
if search_key != key and len(set(search_values) & set(values)) >= 3
]
print(common_items)
[('item1', 'item2', {'C', 'B', 'A'}),
('item2', 'item1', {'C', 'B', 'A'}),
('item2', 'item3', {'C', 'D', 'A'}),
('item2', 'item4', {'C', 'D', 'B'}),
('item3', 'item2', {'C', 'D', 'A'}),
('item4', 'item2', {'C', 'D', 'B'})]
This question already has answers here:
How can I create a Set of Sets in Python?
(4 answers)
Closed 3 years ago.
If you have a list of sets like this:
a_list = [{'a'}, {'a'}, {'a', 'b'}, {'a', 'b'}, {'a', 'c', 'b'}, {'a', 'c', 'b'}]
How could one get the number of unique sets in the list?
I have tried:
len(set(a_list ))
I am getting the error:
TypeError: unhashable type: 'set'
Desired output in this case is: 3 as there are three unique sets in the list.
You can use a tuple:
a_list = [{'a'}, {'a'}, {'a', 'b'}, {'a', 'b'}, {'a', 'c', 'b'}, {'a', 'c', 'b'}]
result = list(map(set, set(map(tuple, a_list))))
print(len(result))
Output:
[{'a', 'b'}, {'a'}, {'c', 'a', 'b'}]
3
A less functional approach, perhaps a bit more readable:
result = [set(c) for c in set([tuple(i) for i in a_list])]
How about Converting to a tuple:
a_list = [{'a'}, {'a'}, {'a', 'b'}, {'a', 'b'}, {'a', 'c', 'b'}, {'a', 'c', 'b'}]
print(len(set(map(tuple, a_list))))
OUTPUT:
3
I know this is possible with list comprehension but I can't seem to figure it out. Currently I have a list of dictionaries like so:
[ {'field1': 'a', 'field2': 'b'},
{'field1': 'c', 'field2': 'd'},
{'field1': 'e', 'field2': 'f'} ]
I'm trying to turn this into:
list = [
['b', 'a'],
['d', 'c'],
['f', 'e'],
]
You can try:
[[x['field2'], x['field1']] for x in l]
where l is your input list. The result for your data would be:
[['b', 'a'], ['d', 'c'], ['f', 'e']]
This way you ensure that the value for field2 comes before the value for field1
Just return the dict.values() lists in Python 2, or convert the dictionary view to a list in Python 3:
[d.values() for d in list_of_dicts] # Python 2
[list(d.values()) for d in list_of_dicts] # Python 3
Note that the values are not going to be in any specific order, because dictionaries are not ordered. If you expected them to be in a given order you'd have to add a sorting step.
I'm not sure what ordering you want, but for no order you could do:
list_ = [list(_.values()) for _ in dict_list]
You can use list comprehension
Python 3
>>>listdict = [ {'field1': 'a', 'field2': 'b'},
... {'field1': 'c', 'field2': 'd'},
... {'field1': 'e', 'field2': 'f'} ]
>>>[[a for a in dict.values()] for dict in listdict]
[['b', 'a'], ['d', 'c'], ['f', 'e']]
Python 2
>>>[dict.values() for dict in listdict]
[['b', 'a'], ['d', 'c'], ['f', 'e']]