Список Python транспонировать и заполнить
у меня есть список списков, такой, что длина каждого внутреннего списка равна 1 или n (предположим, n > 1).
>>> uneven = [[1], [47, 17, 2, 3], [3], [12, 5, 75, 33]]
Я хочу транспонировать список, но вместо усечения длинного списка (как с zip
) или заполнение более коротких списков None
, Я хочу заполнить более короткие списки своим собственным сингулярным значением. Другими словами, Я хотел бы получить:
>>> [(1, 47, 3, 12), (1, 17, 3, 5), (1, 2, 3, 75), (1, 3, 3, 33)]
Я могу сделать это с помощью нескольких итераций:
>>> maxlist = len(max(*uneven, key=len))
>>> maxlist
4
>>> from itertools import repeat
>>> uneven2 = [x if len(x) == maxlist else repeat(x[0], maxlist) for x in uneven]
>>> uneven2
[[1, 1, 1, 1], [47, 17, 2, 3], [3, 3, 3, 3], [12, 5, 75, 33]]
>>> zip(*uneven2)
[(1, 47, 3, 12), (1, 17, 3, 5), (1, 2, 3, 75), (1, 3, 3, 33)]
но есть ли лучший подход? Делать Мне действительно нужно знать maxlist
заранее для этого?
3 ответов
вы можете повторить один список элементов навсегда:
uneven = [[1], [47, 17, 2, 3], [3], [12, 5, 75, 33]]
from itertools import repeat
print zip(*(repeat(*x) if len(x)==1 else x for x in uneven))
можно использовать itertools.cycle()
вместо:
>>> from itertools import cycle
>>> uneven3 = [x if len(x) != 1 else cycle(x) for x in uneven]
>>> zip(*uneven3)
[(1, 47, 3, 12), (1, 17, 3, 5), (1, 2, 3, 75), (1, 3, 3, 33)]
это означает, что вам не нужно знать maxlist
раньше времени.
мне очень понравилась идея @chris-morgan о моделировании itertools.izip_longest
, поэтому, когда у меня наконец появилось вдохновение, я написал