3

I am new to python so I am trying to figure out how to use a generator expression with tuples of integers.

I have the following construct:

Number of Polygons: 3
Blocked Polygons:

{
    0:(6, 192, 365, 172, 388, 115, 378, 127, 311, 142, 305, 192, 334), 
    1:(4, 172, 688, 115, 678, 105, 650, 107, 634), 
    2:(6, 242, 294, 215, 278, 205, 250, 242, 205, 284, 221, 292, 234)
}

Where Blocked Polygons is a dictionary object the first item 6, 192, 365...etc.. where 6 is the number of coordinates in that list.

What I want to convert it to is a dictionary of coordinate dictionaries that looks like this:

{
    0:{
        0:(192, 365),  
        1:(172, 388), 
        2:(115, 378), 
        3:(127, 311),
        4:(142, 305), 
        5:(192, 334)
    },
}, etc... 

any ideas on how to do this effectively?

Serdalis
  • 10,296
  • 2
  • 38
  • 58
fossl
  • 67
  • 1
  • 9
  • The grouper recipe illustrated in [this SO answer](http://stackoverflow.com/a/434411/2823755) should help. – wwii Sep 10 '15 at 04:18

3 Answers3

2

Here is one way, example shown for the first dictionary key:

data = {
    0: (6, 192, 365, 172, 388, 115, 378, 127, 311, 142, 305, 192, 334), 
    1: (4, 172, 688, 115, 678, 105, 650, 107, 634), 
    2: (6, 242, 294, 215, 278, 205, 250, 242, 205, 284, 221, 292, 234)
}

it = iter(data[0][1:])
result = dict(enumerate(zip(it, it)))
from pprint import pprint
pprint(result)

Output

{0: (192, 365),
 1: (172, 388),
 2: (115, 378),
 3: (127, 311),
 4: (142, 305),
 5: (192, 334)}

You can do all keys in data like this:

results = {}
for k, v in data.items():
    it = iter(v[1:])
    results.update({k: dict(enumerate(zip(it, it)))})
pprint(results)

Output

{0: {0: (192, 365),
     1: (172, 388),
     2: (115, 378),
     3: (127, 311),
     4: (142, 305),
     5: (192, 334)},
 1: {0: (172, 688), 1: (115, 678), 2: (105, 650), 3: (107, 634)},
 2: {0: (242, 294),
     1: (215, 278),
     2: (205, 250),
     3: (242, 205),
     4: (284, 221),
     5: (292, 234)}}
mhawke
  • 84,695
  • 9
  • 117
  • 138
1

This is somewhat arcane but will do exactly what you want using comprehensions, assuming the variable poly starts out containing your original value:

print( {pkey:{n:(v[n],v[n+1]) for n in range(1,len(v),2)} for pkey,v in poly.items()} )

In general, I'd say that's not very "Pythonic" because it's somewhat difficult to read. I'd be tempted to visit your original data structures and see if you create a class which would encapsulate the behavior somehow.

Gary Wisniewski
  • 1,080
  • 10
  • 9
1

You could do this:

d = {
    0: (6, 192, 365, 172, 388, 115, 378, 127, 311, 142, 305, 192, 334), 
    1: (4, 172, 688, 115, 678, 105, 650, 107, 634), 
    2: (6, 242, 294, 215, 278, 205, 250, 242, 205, 284, 221, 292, 234)
}

pprint({k: dict(enumerate(zip(vs[1::2], vs[2::2]))) for k, vs in d.iteritems()})

Note that the first element in each tuple can be ignored unless you need to do some error checking.

Output:

{0: {0: (192, 365),
     1: (172, 388),
     2: (115, 378),
     3: (127, 311),
     4: (142, 305),
     5: (192, 334)},
 1: {0: (172, 688), 1: (115, 678), 2: (105, 650), 3: (107, 634)},
 2: {0: (242, 294),
     1: (215, 278),
     2: (205, 250),
     3: (242, 205),
     4: (284, 221),
     5: (292, 234)}}
YS-L
  • 14,358
  • 3
  • 47
  • 58