【问题标题】:Python Output LengthPython 输出长度
【发布时间】:2016-08-13 14:37:22
【问题描述】:

我正在尝试输出我的数据库表数据,除了长表行之外,它还可以工作。列需要与最长的数据库行一样大。当输出长行时(不使用第三方库,例如Print results in MySQL format with Python),我无法执行计算以按比例正确输出表格,而不是造成巨大的混乱。如果您需要更多信息,请告诉我。

数据库连接:

connection = sqlite3.connect("test_.db")
c = connection.cursor()

 c.execute("SELECT * FROM MyTable")
          results = c.fetchall()
          formatResults(results)

表格格式:

def formatResults(x):
    try: 
          widths = []
          columns = []
          tavnit = '|'
          separator = '+' 

          for cd in c.description:
                widths.append(max(cd[2], len(cd[0])))
                columns.append(cd[0])

          for w in widths:
                tavnit += " %-"+"%ss |" % (w,)
                separator += '-'*w + '--+'

          print(separator)
          print(tavnit % tuple(columns))
          print(separator)
          for row in x:
              print(tavnit % row)
          print(separator)
          print ""
    except:
        showMainMenu()
        pass

输出问题示例:

+------+------+---------+
| Date | Name | LinkOrFile |
+------+------+---------+
| 03-17-2016 | hi.com | Locky |
| 03-18-2016 | thisisitsqq.com | None    |
| 03-19-2016 | http://ohiyoungbuyff.com\69.exe?1 | None    |
| 03-20-2016 | http://thisisitsqq..com\69.exe?1 | None    |
| 03-21-2016 | %Temp%\zgHRNzy\69.exe | None    |
| 03-22-2016 |      | None    |
| 03-23-2016 | E52219D0DA33FDD856B2433D79D71AD6 | Downloader |
| 03-24-2016 | microsoft.com | None    |
| 03-25-2016 | 89.248.166.132 | None    |
| 03-26-2016 | http://89.248.166.131/55KB5js9dwPtx4= | None    |

【问题讨论】:

  • 您面临的具体问题是什么?
  • 你打印了可变宽度的输出吗?它是否包含每列最长值的长度?
  • 我不知道该怎么做。
  • formatResults第一次循环后,添加行print widths
  • 好的,我明白了:[4] [4, 4] [4, 4, 7]

标签: python mysql python-2.7 sqlite python-3.x


【解决方案1】:

如果您的主要问题是使所有行的列宽保持一致,这个 python 包可以完成这项工作:https://pypi.python.org/pypi/tabulate

您可以在下面找到一个可能的格式化方法的非常简单的示例。 关键是找到每一列的最大长度,然后使用字符串对象的format方法:

#!/usr/bin/python

import random
import string
from operator import itemgetter


def randomString(minLen = 1, maxLen = 10):
    """ Random string of length between 1 and 10 """
    l = random.randint(minLen, maxLen)
    return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(l))

COLUMNS = 4

def randomTable():
    table = []
    for i in range(10):
        table.append( [randomString() for j in range(COLUMNS)] )
    return table

def findMaxColumnLengs(table):
    """ Returns tuple of max column lengs """
    maxLens = [0] * COLUMNS
    for l in table:
        lens = [len(s) for s in l]
        maxLens = [max(maxLens[e[0]], e[1]) for e in enumerate(lens)]

    return maxLens



if __name__ == '__main__':
    ll = randomTable()

    ml = findMaxColumnLengs(ll)

    # tuple of formatting statements, see format docs
    formatStrings = ["{:<%s}" % str(m) for m in ml ]
    fmtStr = "|".join(formatStrings)

    print "=================================="
    for l in ll:
        print l
    print "=================================="
    for l in ll:
        print fmtStr.format(*l)

这将打印包含在列表列表和格式化输出中的初始表。

==================================
['2U7Q', 'DZK8Z5XT', '7ZI0W', 'A9SH3V3U']
['P7SOY3RSZ1', 'X', 'Z2W', 'KF6']
['NO8IEY9A', '4FVGQHG', 'UGMJ', 'TT02X']
['9S43YM', 'JCUT0', 'W', 'KB']
['P43T', 'QG', '0VT9OZ0W', 'PF91F']
['2TEQG0H6A6', 'A4A', '4NZERXV', '6KMV22WVP0']
['JXOT', 'AK7', 'FNKUEL', 'P59DKB8']
['BTHJ', 'XVLZZ1Q3H', 'NQM16', 'IZBAF']
['G0EF21S', 'A0G', '8K9', 'RGOJJYH2P9']
['IJ', 'SRKL8TXXI', 'R', 'PSUZRR4LR']
==================================
2U7Q      |DZK8Z5XT |7ZI0W   |A9SH3V3U  
P7SOY3RSZ1|X        |Z2W     |KF6       
NO8IEY9A  |4FVGQHG  |UGMJ    |TT02X     
9S43YM    |JCUT0    |W       |KB        
P43T      |QG       |0VT9OZ0W|PF91F     
2TEQG0H6A6|A4A      |4NZERXV |6KMV22WVP0
JXOT      |AK7      |FNKUEL  |P59DKB8   
BTHJ      |XVLZZ1Q3H|NQM16   |IZBAF     
G0EF21S   |A0G      |8K9     |RGOJJYH2P9
IJ        |SRKL8TXXI|R       |PSUZRR4LR 

【讨论】:

  • 他不想使用包,正如他的问题所提到的。
  • 是的,我想在没有包的情况下这样做。
  • 对不起,我忽略了这一点。我添加了一个示例
【解决方案2】:

您使用的代码用于 MySQL。关键部分是widths.append(max(cd[2], len(cd[0]))) 行,其中cd[2] 给出了该列中最长数据的长度。这适用于 MySQLdb。

但是,您使用的是 sqlite3,其值 cd[2] 设置为 Nonehttps://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.description

因此,您将需要替换以下逻辑:

 for cd in c.description:
                widths.append(max(cd[2], len(cd[0])))
                columns.append(cd[0])

用你自己的。只要正确计算widths,其余代码应该没问题。

正确获取widths 变量的最简单方法是遍历结果的每一行并找出每列的最大宽度,然后将其附加到widths。这只是一些伪代码

for cd in c.description:
   columns.append(cd[0])  # Get column headers

widths = [0] * len(c.description)   # Initialize to number of columns.
for row in x:
  for i in range(len(row)):  # This assumes that row is an iterable, like list
    v = row[i]  # Take value of ith column
    widths[i] = max(len(v), widths[i]) # Compare length of current value with value already stored

最后,widths 应该包含每列的最大长度。

【讨论】:

  • 好的,我将如何替换您提到的逻辑?请问可以提供样品吗?
  • 我不知道该怎么做。
  • 这可行,但它不返回单值查询,例如 Count(*)。关于那个有什么想法吗?
  • 可能与 widths 的初始化方式有关。见编辑。
  • Count(*) 函数和大查询结果不显示。
猜你喜欢
  • 1970-01-01
  • 2018-09-17
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-18
  • 2011-03-24
相关资源
最近更新 更多