Home > database >  how to create all pairs in a more pythonic way?
how to create all pairs in a more pythonic way?

Time:07-02

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}
  • Related