0

我正在尝试根据列表中的项目数创建格式字符串变量

d = {1: ['Spices', 39], 2: ['Cannons', 43], 3: ['Tea', 31], 4: ['Contraband', 46], 5: ['Fruit', 38], 6: ['Textiles', 44]} 
d_max = [2, 11, 3]

for k,v in d.items():
    list_var = [k, v[0], v[1]]
    print(("{:<{}} " * 3).format(list_var[0], d_max[0], list_var[1], d_max[1], list_var[2], d_max[2]))

如果键具有或多或少的值而不对响应进行硬编码,我希望它能够工作。我可以在 for 循环中创建一个字符串然后解析和评估它吗?我不知道这样做的语法。或者,如果有一种更 Pythonic 的方式,我也很想知道。

提前致谢。

4

4 回答 4

1

我的印象是您还希望能够将新项目随机添加到每个键的列表中。我很无聊所以我说为什么不写下面的代码。它会找到每个key-value的每个entry的最长的长度,放到d_max中,不管是什么类型,只要能转成字符串,还支持随机往value里加东西(见d) 的最后两行。我试图很好地评论它,但如果你需要的话,请问一些事情。

d = {1: ['Spices', 39],
     2: ['Cannons', 43],
     3: ['Tea', 31],
     4: ['Contraband', 46],
     5: ['Fruit', 38],
     6: ['Textiles', 44],
     7: ['Odds and Ends', 100, 9999],
     8: ['Candies', 9999, 'It\'s CANDY!']} 
d_max = []

# Iterate over keys of d
for k in d:
    # Length of the key
    if len(d_max) <= 0:
        d_max.append(len(str(k)) + 1)
    elif len(str(k))+ 1 > d_max[0]:
        d_max[0] = len(str(k)) + 1 

    # Iterate over the length of the value
    for i in range(len(d[k])):
        # If the index isn't in d_max then this must be the longest
        # Add one to index because index 0 is the key's length
        if len(d_max) <= i+1:
            d_max.append(len(str(d[k][i])))
            continue
        # This is longer than the current one
        elif len(str(d[k][i])) + 1 > d_max[i+1]:
            d_max[i+1] = len(str(d[k][i])) + 1

for k,v in d.items():
    list_var = [k] + v

    # A list of values to unpack into the string
    vals = []
    # Add the value then the length of the space
    for i in range(len(list_var)):
        vals.append(list_var[i])
        vals.append(d_max[i])

    print(("{:<{}} " * len(list_var)).format(*vals))

输出:

1  Spices         39    
2  Cannons        43    
3  Tea            31    
4  Contraband     46    
5  Fruit          38    
6  Textiles       44    
7  Odds and Ends  100   9999         
8  Candies        9999  It's CANDY! 

如果你想把它全部放在一条线上,那么我恐怕帮不了你:(还有一种更清洁的方法来做第二个循环,但这就是我在几个小时的睡眠中所能想到的。

于 2013-06-27T17:23:52.777 回答
0

If I understand your question correctly, this is the format string you want:

"{:<{}} " * len(list_var)

This of course requires, in your particular case, that your lists (d_max and list_var) are both the correct length. But it'll work for any length.

To make the actual use case a little cleaner, I'd probably put the list of arguments together in a separate statement. The general case for your loop could look something like this:

args = []
for i in range(len(list_var)): # Build list of value/width arguments
    args += [list_var[i], d_max[i]]
print(("{:<{}} " * len(list_var)).format(*args))

Or if you're a stickler for one-liners, you could use this monstrosity (does the same thing as the explicit loop above, except that it's much harder to read.):

# Ew
print(("{:<{}} " * len(list_var)).format(*functools.reduce(
                                            lambda a, i: a + [list_var[i], d_max[i]],
                                            range(len(list_var)),
                                            [])))

Finally, as others have noted, you shouldn't rely on a dictionary to preserve order. If it's important that the items are presented in order by their dictionary keys, you should make sure to sort them before you iterate:

for k,v in sorted(d.items()):
于 2013-06-27T16:14:28.647 回答
0

如果我正确理解了您的问题,则以下内容将处理与字典中每个键相关联的更多和更少的值。事实上,每个条目不必在列表中具有相同数量的值。

为了说明这一点,我已经从字典中显示的几个条目中添加和删除了您的代码到下面的条目中的值。前两个之外的值条目将被忽略,但您可以通过d_max根据需要扩展字段宽度列表来轻松容纳更多。

d = {1: ['Spices', 39, 'a'],
     2: ['Cannons', 43, 'b', 'c'],
     3: [],
     4: ['Contraband', 46, 'd'],
     5: ['Fruit'],
     6: ['Textiles', 44, 'f']}

d_max = [2, 11, 3]

for k,v in d.items():
    list_var = [k] + v[:2]
    pairs = (item for pair in zip(list_var, d_max) for item in pair)
    print(("{:<{}} " * len(list_var)).format(*pairs))

输出:

1  Spices      39
2  Cannons     43
3
4  Contraband  46
5  Fruit
6  Textiles    44
于 2013-06-27T20:04:59.387 回答
0

你的意思是你想做类似的事情:

list_var = [k] + v[:2]

如果值列表中有太多项目,这将起作用(它只会删除多余的项目)。

于 2013-06-27T16:06:12.470 回答