Как напечатать набор вложенного списка, как мне нужно в Python 3.6 - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть вложенные, содержащие значения разной длины, так:

[['cat', 123, 'yellow'],
['dog', 12345, 'green'],
[horse', 123456, 'red']]

Я хочу напечатать их так:

cat,   123,    yellow
dog,   12345,  green
horse, 123456, red 

Я пытался использовать pprint для достижения своих целей с помощью следующего кода:

for sub in master_list:

    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(sub)

Где master - это вложенный список и вложенные в него списки. Это, однако, дает мне вывод примерно так:

[
    'cat', 
    123, 
    'yellow'
],

[
    'dog', 
    12345, 
    'green'
],

[
    horse', 
    123456, 
    'red'
]

Существует ли модуль python, который позволяет мне относительно легко достичь того, чего я хочу, без какого-либо извилистого взлома?

Спасибо

Ответы [ 6 ]

0 голосов
/ 17 ноября 2018

Другой способ, учитывая вложенный список:

table = [['cat', 123, 'yellow'],
          ['dog', 12345, 'green'],
          ['horse', 123456, 'red']]

Использование строковых методов:

for line in table:
  print("|", end='')
  for word in line:
    print (f" {word}".ljust(10) + "|", end='')
  print()

Чтобы получить:

| cat      | 123      | yellow   |
| dog      | 12345    | green    |
| horse    | 123456   | red      |
0 голосов
/ 16 ноября 2018

Вы можете сделать это:

spacing = [max(map(lambda x: len(str(x)), d)) for d in zip(*data)]
for row in data:
    for i, elem in enumerate(row):
        e = str(elem) + (',' if i < len(row) -1 else '')
        print('{{:{}}} '.format(spacing[i]+1).format(e), end='')
    print()

Результаты:

cat,      123,      orange  
elephant, 500000,   green   
horse,    123456.0, red  

Пояснения:

spacing определяется путем сбора максимальной длины каждого «столбца» в ваших данных. Мы можем сгруппировать столбцы, используя:

zip(*data)

Который дает транспонированную копию ваших данных следующим образом:

('cat', 'elephant', 'horse'), 
(123, 500000, 123456.0), 
('orange', 'green', 'red')

Затем мы используем функцию map, чтобы применить функцию len(str(x)) к этим столбцам:

(3, 8, 5),
(3, 6, 8), 
(6, 5, 3)

Затем мы просто получаем max каждого столбца, объединяем все в понимании списка и возвращаем его как spacing:

spacing = [max(map(lambda x: len(str(x)), d)) for d in zip(*data)]

Затем, пока мы перебираем ваши данные, мы также хотим enumerate(row), чтобы мы знали, с каким «столбцом» мы работаем. i даст вам индекс столбца в дополнение к фактическому elem.

После этого мы назначаем временный str для добавления запятой, если это не последний элемент:

e = str(elem) + (',' if i < len(row) -1 else '')

Это делает его немного более читаемым, чем добавление его как части параметров формата.

После этого мы используем форматирование строки (или e.ljust(spacing[i] + 1), если хотите), чтобы добавить предопределенный максимум spacing на основе столбца. Обратите внимание, что мы форматируем строку дважды, сначала экранируя внешние фигурные скобки ({{ и }}), поэтому она может быть в последовательности:

'{{:{}}}.format(9).format(e)
# becomes
'{:9}'.format(e)
# becomes
'cat,     '

Обратите внимание на использование end='', чтобы сделать линию печати непрерывной, пока не закончится row. spacing[i] + 1 - учет добавленной запятой.

Я должен признаться, что это может быть не самым эффективным способом, но в зависимости от того, что вы пытаетесь достичь решения, может быть заметно иначе.

0 голосов
/ 16 ноября 2018

Ваш конкретный формат может быть решен путем печати с помощью ljust, чтобы добавить необходимые пробелы:

data = [['cat', 123, 'yellow'],
        ['dog', 12345, 'green'],
        ['horse', 123456, 'red']]

# get the overall widest string as base for right-aligning them 
max_len = max( len(str(x)) for k in data for x in k) 

for inner in data:
    first = True
    for elem in inner[:-1]: # all but the last
        text = "{},".format(elem).ljust(max_len+2)
        print(text,end="")

    print(inner[-1]) # print last

Выход:

cat,    123,    yellow
dog,    12345,  green
horse,  123456, red

Доку:


Обычно для форматирования вы можете использовать мини-язык строкового формата для форматирования выходных данных:

for inner in data:
    first = True
    for elem in inner:
        if first:
            text = "{:<{}} ".format(elem,max_len+2)
            first = False
        else:
            text = ", {:<{}} ".format(elem,max_len+2)
        print(text, end="")
    print("")

Выход:

cat      , 123      , yellow   
dog      , 12345    , green    
horse    , 123456   , red      

Строка формата "{:<{}} ".format(elem,max_len+2), форматы element, выровненные вправо по max_len+2 символам. Суть first состоит в том, чтобы , не появлялся в начале строки.

0 голосов
/ 16 ноября 2018

Панды могут помочь.

import pandas as pd
lst = [['cat', 123, 'yellow'], ['dog', 12345, 'green'], ['horse', 123456, 'red']]
df = pd.DataFrame(lst)
print(df)

Выход:

    0   1   2
0   cat     123     yellow
1   dog     12345   green
2   horse   123456  red
0 голосов
/ 16 ноября 2018

Вы можете использовать это:

a = [['cat', 123, 'yellow'], ['dog', 12345, 'green'], ['horse', 123456, 'red']]

# Get the max length of string in the list
m = max([len(str(x)) for y in a for x in y])

# Use the format specifier in Python print function:
# Example: print '{:10s} {:3d}  {:7.2f}'.format('xxx', 123, 98)
# This prints : xxx        123    98.00
# We will create the string as {:6s}, here 6 is the length in our case and will be generated dynamically using 'm'

list(map(lambda x: print('\t'.join(list(map(lambda y:   str('{' + ':{m}s'.format(m=m) +'}').format(str(y)), x)))), a))

Выход:

cat     123     yellow
dog     12345   green 
horse   123456  red
0 голосов
/ 16 ноября 2018

Вы можете использовать следующий код:

myLst = [['cat', 123, 'yellow'],
['dog', 12345, 'green'],
['horse', 123456, 'red']]

for subLst in myLst:
    print("\t".join([str(ele) for ele in subLst]))

Что печатает вывод так:

cat    123      yellow
dog    12345    green
horse  123456   red

Если вы хотите иметь ",", просто измените строку

print("\t".join([str(ele) for ele in subLst]))

до

print(",\t".join([str(ele) for ele in subLst]))

И полная вещь как однострочная:

print("\n".join([",\t".join([str(ele) for ele in subLst]) for subLst in myLst]))

Или, если вам нужна функция:

def printLst(myLst):
    print("\n".join([",\t".join([str(ele) for ele in subLst]) for subLst in myLst]))

Редактировать

Как отмечено в комментариях, это также хороший пример использования функции python map. Который может быть использован для того, чтобы сделать все короче;)

...