I have a json like the following:
[
["s5"],
["s7"],
["s9","s773"],
["s4","s17"]
]
I have to create a dictionary like:
{
s5_s7 = False
s5_s9 = False,
s5_s773 = False,
s5_s4 = False,
s5_s17 = False,
s7_s9 = False,
s7_s773 = False,
s7_s4 = False,
s7_s17 = False,
s9_s773 = True
s9_s4 = False
s9_s17 = True
s4_s17 = True
}
Currently, I am looping over the json structure using for loop and then for each entry I am looping with for loop as well.
Is there a more pythonic way to implement without my ad-hoc implementation with for loops?
CodePudding user response:
Comparing Zach Flanders solution to a more standard approach which is about 2x time faster. Also his solution (solution b in my exemple) include "duplicate" such as s4_s4 and solution a do not.
import timeit
def solution_a():
items = [
["s5"],
["s7"],
["s9","s773"],
["s4","s17"]
]
res = {}
for row in items:
for cell in row:
for new_row in items:
for new_cell in new_row:
if new_cell == cell:
continue
if new_cell not in row:
res[f"{new_cell}_{cell}"] = False
else:
res[f"{new_cell}_{cell}"] = True
return res
def solution_b():
from itertools import chain, product
foo = [
["s5"],
["s7"],
["s9","s773"],
["s4","s17"]
]
bar = set(chain(*[
["s5"],
["s7"],
["s9","s773"],
["s4","s17"]
]))
baz = set(product(bar, bar))
result = {
'_'.join(i): list(i) in foo
for i in baz
}
return result
print(timeit.timeit(stmt=solution_a, number=100))
print(timeit.timeit(stmt=solution_b, number=100))
0.0010075382888317108
0.002192392945289612
Respective results
{'s7_s5': False, 's9_s5': False, 's773_s5': False, 's4_s5': False, 's17_s5': False, 's5_s7': False, 's9_s7': False, 's773_s7': False, 's4_s7': False, 's17_s7': False, 's5_s9': False, 's7_s9': False, 's773_s9': True, 's4_s9': False, 's17_s9': False, 's5_s773': False, 's7_s773': False, 's9_s773': True, 's4_s773': False, 's17_s773': False, 's5_s4': False, 's7_s4': False, 's9_s4': False, 's773_s4': False, 's17_s4': True, 's5_s17': False, 's7_s17': False, 's9_s17': False, 's773_s17': False, 's4_s17': True}
{'s7_s5': False, 's7_s9': False, 's9_s7': False, 's17_s5': False, 's4_s7': False, 's17_s9': False, 's7_s17': False, 's5_s5': False, 's7_s773': False, 's5_s9': False, 's9_s5': False, 's4_s5': False, 's773_s4': False, 's17_s17': False, 's9_s9': False, 's17_s773': False, 's4_s9': False, 's5_s17': False, 's5_s773': False, 's9_s17': False, 's4_s17': True, 's9_s773': True, 's4_s773': False, 's7_s4': False, 's773_s7': False, 's17_s4': False, 's5_s4': False, 's773_s5': False, 's9_s4': False, 's4_s4': False, 's7_s7': False, 's773_s9': False, 's17_s7': False, 's773_s17': False, 's773_s773': False, 's5_s7': False}
CodePudding user response:
You can use chain and product from itertools to first flatten the list into a set of unique items, then find the product of the set, then check to see if each product is in the original list:
from itertools import chain, product
foo = [
["s5"],
["s7"],
["s9","s773"],
["s4","s17"]
]
bar = set(chain(*[
["s5"],
["s7"],
["s9","s773"],
["s4","s17"]
]))
baz = set(product(bar, bar))
result = {
'_'.join(i): list(i) in foo
for i in baz
}
print(result)
Output
{'s9_s17': False,
's773_s773': False,
's5_s773': False,
's4_s17': True,
's7_s17': False,
's9_s7': False,
's773_s5': False,
's4_s7': False,
's7_s7': False,
's5_s5': False,
's9_s4': False,
's9_s9': False,
's17_s17': False,
's4_s4': False,
's4_s9': False,
's7_s4': False,
's9_s773': True,
's7_s9': False,
's17_s7': False,
's4_s773': False,
's5_s4': False,
's7_s773': False,
's17_s4': False,
's17_s9': False,
's773_s17': False,
's9_s5': False,
's4_s5': False,
's5_s17': False,
's7_s5': False,
's17_s773': False,
's773_s7': False,
's5_s7': False,
's773_s4': False,
's773_s9': False,
's17_s5': False,
's5_s9': False}