Search code examples
pythonpython-3.xrefactoringcode-cleanup

how to create all pairs in a more pythonic way?


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?


Solution

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