Выровнять числа в подсписке

У меня есть набор чисел, которые я хочу выровнять с учетом запятой:

10 3 200 4000,222 3 1,5 200,21 0,3 2 30000 4,5 1 mylist = [['10', '3', '', ''], ['200', '4000,222', '3', '1,5'], ['200,21', '', '0,3', '2'], ['30000', '4,5', '1', '']] 

Я хочу, чтобы выровнять этот список с запятой:

ожидаемый результат:

 mylist = [[' 10 ', ' 3 ', ' ', ' '], [' 200 ', '4000,222', '3 ', '1,5'], [' 200,21', ' ', '0,3', '2 '], ['30000 ', ' 4,5 ', '1 ', ' ']] 

Я попытался перевернуть список:

 mynewlist = list(zip(*mylist)) 

и найти самую длинную часть после запятой в каждом подсписке:

 for m in mynewlist: max([x[::-1].find(',') for x in m] 

и использовать rjust и ljust, но я не знаю, как исправить после запятой и rjust перед запятой, как в той же веревке.

Как я могу разрешить это без использования format ()? (Я хочу совместить с ljust и rjust)

    Вот еще один подход, который в настоящее время делает трюк. К сожалению, я не вижу никакого простого способа сделать эту работу, возможно, из-за времени 🙂

    В любом случае, я объясню это. r – это список результатов, созданный вручную.

     r = [[] for i in range(4)] 

    Затем мы перебираем значения, а также захватываем индекс с enumerate :

     for ind1, vals in enumerate(zip(*mylist)): 

    Внутри цикла мы получаем максимальную длину десятичных цифр и максимальную длину слова (слово без десятичных цифр):

      l = max(len(v.partition(',')[2]) for v in vals) + 1 mw = max(len(v if ',' not in v else v.split(',')[0]) for v in vals) 

    Теперь мы переходим через значения внутри tuple vals и строим наши результаты (yup, в настоящее время не можем думать о способе избежать этой вложенности).

      for ind2, v in enumerate(vals): 

    Если он содержит запятую, его следует отформатировать по-разному. В частности, мы rjust его на основе максимальной длины слова mw а затем добавляем десятичные цифры и любое требуемое пространство:

      if ',' in v: n, d = v.split(',') v = "".join((n.rjust(mw),',', d, " " * (l - 1 - len(d)))) 

    В противном случае мы просто просто добавляем пробелы:

      else: v = "".join((v.rjust(mw) + " " * l)) 

    наконец, append к r .

      r[ind1].append(v) 

    Все вместе:

     r = [[] for i in range(4)] for ind1, vals in enumerate(zip(*mylist)): l = max(len(v.partition(',')[2]) for v in vals) + 1 mw = max(len(v if ',' not in v else v.split(',')[0]) for v in vals) for ind2, v in enumerate(vals): if ',' in v: n, d = v.split(',') v = "".join((n.rjust(mw),',', d, " " * (l - 1 - len(d)))) else: v = "".join((v.rjust(mw) + " " * l)) r[ind1].append(v) 

    Теперь мы можем распечатать его:

     >>> print(*map(list,zip(*r)), sep='\n) [' 10 ', ' 3 ', ' ', ' '] [' 200 ', '4000,222', '3 ', '1,5'] [' 200,21', ' ', '0,3', '2 '] ['30000 ', ' 4,5 ', '1 ', ' '] 

    Вот немного другое решение, которое не переносит my_list но вместо этого my_list его дважды. На первом проходе он генерирует список кортежей, по одному для каждого столбца. Каждый кортеж представляет собой пару чисел, где первое число имеет длину до запятой, а второе число – это длина запятой и все, что следует за ней. Например, '4000,222' приводит к (4, 4) . На втором проходе он форматирует данные на основе информации форматирования, сгенерированной при первом проходе.

     from functools import reduce mylist = [['10', '3', '', ''], ['200', '4000,222', '3', '1,5'], ['200,21', '', '0,3', '2'], ['30000', '4,5', '1', '']] # Return tuple (left part length, right part length) for given string def part_lengths(s): left, sep, right = s.partition(',') return len(left), len(sep) + len(right) # Return string formatted based on part lengths def format(s, first, second): left, sep, right = s.partition(',') return left.rjust(first) + sep + right.ljust(second - len(sep)) # Generator yielding part lengths row by row parts = ((part_lengths(c) for c in r) for r in mylist) # Combine part lengths to find maximum for each column # For example data it looks like this: [[5, 3], [4, 4], [1, 2], [1, 2]] sizes = reduce(lambda x, y: [[max(z) for z in zip(a, b)] for a, b in zip(x, y)], parts) # Format result based on part lengths res = [[format(c, *p) for c, p in zip(r, sizes)] for r in mylist] print(*res, sep='\n') 

    Вывод:

     [' 10 ', ' 3 ', ' ', ' '] [' 200 ', '4000,222', '3 ', '1,5'] [' 200,21', ' ', '0,3', '2 '] ['30000 ', ' 4,5 ', '1 ', ' '] 

    Это работает для python 2 и 3. Я не использовал ljust или rjust, хотя, я просто добавил столько же пробелов до и после числа, сколько не хватает для максимального номера в столбце:

     mylist = [['10', '3', '', ''], ['200', '4000,222', '3', '1,5'], ['200,21', '', '0,3', '2'], ['30000', '4,5', '1', '']] transposed = list(zip(*mylist)) sizes = [[(x.index(",") if "," in x else len(x), len(x) - x.index(",") if "," in x else 0) for x in l] for l in transposed] maxima = [(max([x[0] for x in l]), max([x[1] for x in l])) for l in sizes] withspaces = [ [' ' * (maxima[i][0] - sizes[i][j][0]) + number + ' ' * (maxima[i][1] - sizes[i][j][1]) for j, number in enumerate(l)] for i, l in enumerate(transposed)] result = list(zip(*withspaces)) 

    Печать результата в python3:

     >>> print(*result, sep='\n') (' 10 ', ' 3 ', ' ', ' ') (' 200 ', '4000,222', '3 ', '1,5') (' 200,21', ' ', '0,3', '2 ') ('30000 ', ' 4,5 ', '1 ', ' ')