【问题标题】:Adding or subtracting columns/rows in a table based on user input with Python根据用户使用 Python 输入在表中添加或减去列/行
【发布时间】:2021-07-16 02:05:17
【问题描述】:

我正在编辑这篇文章,因为我没有很好地解释我的问题,所以又来了。我正在使用制表库。我希望使用input() 根据给定的输入自动调整表中的列/行数。这是一个基本示例:

#!/bin/python3
from tabulate import tabulate
uid1 = input('UID > ')
uid2 = input('UID > ')
name1 = input('NAME > ')
name2 = input('NAME > ')
number1 = input('NUMBER > ')
number2 = input('NUMBER > ')
headers = ["UID", "NAME","NUMBER"]
table = [[uid1,name1,number1],[uid2,name2,number2]]
print(tabulate(table, headers, tablefmt="fancy_grid"))
╒═══════╤═════════╤══════════╕
│   UID │ NAME    │ NUMBER   │
╞═══════╪═════════╪══════════╡
│     0 │ SHAWN   │ 333-4444 │
├───────┼─────────┼──────────┤
│     1 │ MICHAEL │ 222-3333 │
╘═══════╧═════════╧══════════╛

但下次脚本运行时,列/表会更多:

╒═══════╤════════╤══════════╕
│   UID │ NAME   │ NUMBER   │
╞═══════╪════════╪══════════╡
│     0 │ JAMES  │ 444-5555 │
├───────┼────────┼──────────┤
│     1 │ ANDREW │ 666-3333 │
├───────┼────────┼──────────┤
│     2 │ SHAWN  │ 444-3333 │
╘═══════╧════════╧══════════╛

所以我试图找出一种方法来使用 for 循环或其他方式调整行和列的给定值,但我无法弄清楚。我想要类似的东西:

UIDs = input('Enter all UIDs $ ')
NAMES = input('Enter all names $ ')
NUMBERS = int(input('Enter all numbers $')

【问题讨论】:

  • 你为什么要使用字符串格式? split() 给你一个字符串列表,然后你出于某种原因使用字符串格式化来构建一个相同的字符串列表。
  • 如果您询问是否有一种方法可以迭代变量,那么我建议您详细说明您希望实现的目标。可以这样做,但这是一种主要的反模式,很可能不是您想要做的。
  • 我不知道为什么我很难解释。因此,不必将尽可能多的值放入 headerstable = [[f"{dataone}",f"{datatwo}]] 中,有没有办法在用户输入时自动添加尽可能多的值?
  • 有了这个:table = [[f"{dataone}",f"{datatwo}]],我必须做dataone = input('dataone: ')才能分配值。不必每次都编辑它,说一件事我只需要两个条目,另一件事我需要 4 个,我必须将 table = [[f"{dataone}",f"{datatwo}]] 编辑为 table = [[f"{dataone}",f"{datatwo}",f"{datathree}",f"{datafour}"]] 然后下次更改它。我可以这样做:AllData = input('blah>>> ').split() 然后也许是for Data in AllData: make room for values

标签: python variables string-formatting tabulate


【解决方案1】:

您可以使用whilefor 循环:

代码

from tabulate import tabulate

def adjust_columns_sizes(columns):
    """
    Adjusts the size of all the
    columns to be the same.
    
    If a column is smaller than
    the biggest, empty strings are added.
    
    Returns a list of lists of strings
    with fixed size.
    
    [['data1', 'data2', 'data3'], <-- column
     ['data']]                    <-- column
    
       ||
       ||
       \/
       
    [['data1', 'data2', 'data3'], <-- column
     ['data', '', '']]            <-- column
    """
    
    columns_sizes = []  # The size of each column
    for column in columns:
        columns_sizes.append(len(column))
    
    # Biggest column size is needed to adjust the
    # smaller columns to the same size.
    biggest_column_size = max(columns_sizes)
    
    # This loop adjust the smaller columns
    fixed_size_columns = []
    for i_column, column in enumerate(columns):  # Enumerate to get the index
        column_length = columns_sizes[i_column]
        if column_length < biggest_column_size:
            
            # Difference of lengths to know how many blank strings
            # to add.
            diff = biggest_column_size - len(column)
            
            # Using list comprehension, and adding of list, the blank
            # strings get added.
            column_with_new_size = column + ['' for _ in range(diff)]
            
            fixed_size_columns.append(column_with_new_size)
        else:
            # If column size is the same as the biggest, just add
            # to the list
            fixed_size_columns.append(column)

    return fixed_size_columns
        
    

def get_headers():
    """
    This function asks for all the headers
    that will be in the table.
    
    Returns a list of strings
    
    ['header', ...]
    """
    
    print('--HEADERS--')
    headers = []  # Headers stored in a list
    while True:
        new_h = input('New header value: ')
        if new_h == '':  # When no value is provided, while loop ends
            break
        headers.append(new_h)

    return headers


def get_body(headers):
    """
    This function asks for the data that will
    be in each column. 
    
    The number of columns is equivalent to the 
    number of headers or the lenght of the list 
    of headers.
    
    Each column will result in a list, but in order to be
    pased as an argument for tabulate, each list
    has to be a row, so we need to transpose
    the columns to rows using the zip function.
    
    Returns a list of tuples of strings. 
    
    [('data', ...), ('data', ...), ...]
    """

    print('--BODY--')
    body = []  # This list will contain the column lists
    for header in headers:
        
        # Message to show for each header
        i_msg = 'Enter all ' + header.lower() + '\'s separated by spaces: '
        
        # getting the data
        data_for_column = input(i_msg)  
        
        # getting a list splitting the data
        column = data_for_column.split()  
        
        body.append(column)
        
    # Adjusting the column sizes in order to zip to work properly
    adjusted_body = adjust_columns_sizes(body)
    
    # Transpose the columns to rows.
    # Using the * operator to pass every column in the list.
    # Using list() because zip returns an iterable object.
    transposed = list(zip(*adjusted_body))
   
    return transposed


if __name__ == '__main__':
    # Getting table headers
    headers = get_headers()
    
    # Getting the data en each column for each header
    # but transposed as rows
    table = get_body(headers)
    
    print(tabulate(table, headers, tablefmt="fancy_grid"))

结果

--HEADERS--
New header value: UID
New header value: NAME
New header value: NUMBER
New header value:
--BODY--
Enter all uid's separated by spaces: 0 1 2 3
Enter all name's separated by spaces: SHAWN MICHAEL JAMES ANDREW
Enter all number's separated by spaces: 333-444 222-333 444-555
╒═══════╤═════════╤══════════╕
│   UID │ NAME    │ NUMBER   │
╞═══════╪═════════╪══════════╡
│     0 │ SHAWN   │ 333-444  │
├───────┼─────────┼──────────┤
│     1 │ MICHAEL │ 222-333  │
├───────┼─────────┼──────────┤
│     2 │ JAMES   │ 444-555  │
├───────┼─────────┼──────────┤
│     3 │ ANDREW  │          │
╘═══════╧═════════╧══════════╛

【讨论】:

  • 谢谢@Kyostenas,这真的很好用,我只是希望我能更好地遵循正在做的事情。
  • 嗨@WaXxX333。我迟到了,但我对其进行了编辑以添加一些更改以重新组合更多您想要的内容。还试图让它更容易理解。
  • 这绝对令人难以置信。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多