1

So, I've generated a list of lists of nested tuples (vectors for a chess move authenticator).

old_v = [[((4, 1, 'P', 'e2'), 1), ((4, 2, '1', 'e3'), 0), ((4, 3, '1', 'e4'), 0), ((4, 4, '1', 'e5'), 0), ((4, 5, '1', 'e6'), 0), ((4, 6, 'q', 'e7'), -1)]]

After reading documentation here and here, I still wasn't able to figure out how to collapse just the tuples from inside each sub-list without rewriting the whole tuple, like this:

new_v = [[(a[b][0][0], a[b][0][1], a[b][0][2], a[b][0][3], a[b][1]) for b in range(0, len(a))] for a in old_v]

print(new_v)

I'd like to know if there's a more Pythonic way to do this.

Joshua Harwood
  • 337
  • 1
  • 2
  • 15

2 Answers2

2
[(a[b][0][0], a[b][0][1], a[b][0][2], a[b][0][3], a[b][1]) for b in range(0, len(a))]

All of the references to b are as a[b], so you can loop over the elements directly instead of going through indexes:

[(b[0][0], b[0][1], b[0][2], b[0][3], b[1]) for b in a]

Tuple unpacking can make b[0] and b[1] more readable and meaningful if you have good names for them:

[(move[0], move[1], move[2], move[3], idk) for move, idk in a]

Finally, iterables can be expanded in tuple literals with a splat:

[(*move, idk) for move, idk in a]
# or [move + (idk,) for move, idk in a] if you prefer

Overall:

new_v = [[(*move, idk) for move, idk in a] for a in old_v]
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • TIL about splat. Appreciative! Also, for those reading, "move" should read "position". These are vectors, listed as lists of quintuples, that show up when pieces are pinned or in check. – Joshua Harwood Jul 25 '20 at 23:49
1

How about this?

l = [((4, 1, 'P', 'e2'), 1), ((4, 2, '1', 'e3'), 0), ((4, 3, '1', 'e4'), 0), ((4, 4, '1', 'e5'), 0), ((4, 5, '1', 'e6'), 0), ((4, 6, 'q', 'e7'), -1)]

def flatten(list_):
    return [(*tup, i) for (tup, i) in list_]

>>> flatten(l)
[(4, 1, 'P', 'e2', 1), (4, 2, '1', 'e3', 1), (4, 3, '1', 'e4', 1), (4, 4, '1', 'e5', 1), (4, 5, '1', 'e6', 1), (4, 6, 'q', 'e7', 1)]
Lord Elrond
  • 13,430
  • 7
  • 40
  • 80