Why does my list productsCombined[] change after running my for loop? How can I change this code so it doesn't? You will see the prints diverge at TAC

huangapple go评论65阅读模式
英文:

Why does my list productsCombined[] change after running my for loop? How can I change this code so it doesn't? You will see the prints diverge at TAC

问题

以下是代码的翻译部分:

我原本希望在for循环运行之前和之后,所有列表都打印相同的值。我认为代码的实际功能不是很相关,但它应该创建4个字符串,这些字符串放在一起时保持相应的文本值在行/空间中正确排列。

例如,代码对列表的影响示例:

![1](https://i.stack.imgur.com/2rqe2.png)

由于某种原因,for循环会更改我的列表的值,当我期望“TAC”是字符串中的下一个产品时,它却以某种方式变成了“Silestone”,字符串中的许多后续产品都不再是其对应的列表值。

```python
import math

productsCombined = ['Silestone', '4in. Backsplash', 'Half-Bullnose Edge ', 'BulletProof®', 'Custom Radius Corner', 'Waterfall', 'Marble (Level 7) (3cm)', 'Custom Height Backsplash', '1/4 Round Edge', 'Regular', 'TAC', '4in. Backsplash', 'Half-Bullnose Edge ', 'Regular', 'Cutouts and Holes', 'K1830402-J', '134BLNO440177', 'W3182716-1', 'US-1512-biscuit', 'P0145402', 'DSA-WD5000', 'Dishwasher Bracket', 'Other', 'Other', 'Template', 'Tear-out and Disposal', 'High Bar Cutdown', 'Standard Install', 'Rush Install', 'Plumbing', 'Layout Approval', 'Payment Method']
descriptionsCombined = ['Name: 1 super mega slab of igneous blue 3cm Counter SQFT: 20.0 Backsplash SQFT: 4.0', 'Using Material 1', 'Material 1. Laminated.', 'Material 1.', 'Material 1. " Corner Radius', 'Material 1.', 'Material 2 - From a Remnant Location: NFM', 'Using Material 2 Height: 24.0"', 'Material 2.', 'Material 2.', 'Material 3. Name: 1 jumbo slab calactatta gold 2cm Counter SQFT: 55.0 Backsplash SQFT: 8.0', 'Using Material 3', 'Material 3. Laminated.', 'Material 3.', '1.0 Undermount Double Sink Cutout(s) 1.0 Undermount Single Sink Cutout(s) 1.0 Overmount Double Sink Cutout(s) 1.0 Overmount Single Sink Cutout(s) 1.0 Appliance Cutout(s) 1.0 Outlet Cutout(s) 1.0 Faucet Hole(s) ', '', '', '', '', '', '', '', '', 'Cobra', 'Leoploredon', 'Ready for Template: No - Waiting on cabinets', '', '', "NOT a 'Rush Job'", 'Install on or Before: 03-22-2023', 'Sinks Requiring Plumbing: 2.0 Bath Sinks 1.0 Kitchen Sinks - Other Plumbing Items: Installation of Garbage Disposal Installation of Water Filter ', '', 'Credit Card (3% Charge)']
quantitiesCombined = ['1.0', '4.0', '5.0', '20.0', '3.0', '2.0', '32.0', '5.0', '5.0', '32.0', '1.0', '8.0', '22.0', '55.0', '1', '1.0', '1.0', '1.0', '1.0', '1.0', '1.0', '1.0', '1', '1', '1', '1', '1', '1', '1', '1', '1']
pricesCombined = ['2560.0', '128.0', '42.0', '10.0', '125.0', '375.0', '62.0', '62.0', '0.0', '2.0', '5280.0', '96.0', '42.0', '2.0', '770.0', '485.0', '850.0', '420.0', '90.0', '100.0', '350.0', '75.0', '120.0', '560.0', '0', '1070.0', '750.0', '0', '1854.2', '1150.0', '0', '598.521']

# 输出
productsString = ""
descriptionsString = ""
quantitiesString = ""
pricesString = ""

for i in range(0, len(productsCombined)):
    print(productsCombined[i])
    linesProducts = math.ceil(len(str(productsCombined[i])) / 47)
    linesDescriptions = math.ceil(len(str(descriptionsCombined[i])) / 47)
    linesQuantities = 1
    linesPrices = 1
    maxLines = max(linesProducts, linesDescriptions)
    if linesProducts >= maxLines:
        productsString += "\n\n" + str(productsCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesProducts
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        productsString += "\n\n" + str(productsCombined[i]) + additionalLines + "_____________________________________"
    if linesDescriptions >= maxLines:
        descriptionsString += "\n\n" + str(descriptionsCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesDescriptions
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        descriptionsString += "\n\n" + str(descriptionsCombined[i]) + additionalLines + "_____________________________________"
    if linesQuantities >= maxLines:
        quantitiesString += "\n\n" + str(quantitiesCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesQuantities
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        quantitiesString += "\n\n" + str(quantitiesCombined[i]) + additionalLines + "_____________________________________"
    if linesPrices >= maxLines:
        pricesString += "\n\n" + str(pricesCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesPrices
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        pricesString += "\n\n" + str(pricesCombined[i]) + additionalLines + "_____________________________________"
    print(productsCombined[i])
    print("\n")

希望这有所帮助!

英文:

I was expecting the lists to all print the same values before and after the for loop is run. I don't think what the code does is as relevant but it is supposed to create 4 strings that when placed next to each other keep the corresponding text values in row / spaced properly.
Ex:

Example of what the code does to the lists

Why does my list productsCombined[] change after running my for loop? How can I change this code so it doesn't? You will see the prints diverge at TAC

For some reason, the for loop is changing the values of my list and when I expect "TAC" to be the next product in the string it is somehow "Silestone" and many of the following products in the string come out as silestone as opposed to their corresponding list value.

import math


productsCombined = ['Silestone', '4in. Backsplash', 'Half-Bullnose Edge ', 'BulletProof®', 'Custom Radius Corner', 'Waterfall', 'Marble (Level 7) (3cm)', 'Custom Height Backsplash', '1/4 Round Edge', 'Regular', 'TAC', '4in. Backsplash', 'Half-Bullnose Edge ', 'Regular', 'Cutouts and Holes', 'K1830402-J', '134BLNO440177', 'W3182716-1', 'US-1512-biscuit', 'P0145402', 'DSA-WD5000', 'Dishwasher Bracket', 'Other', 'Other', 'Template', 'Tear-out and Disposal', 'High Bar Cutdown', 'Standard Install', 'Rush Install', 'Plumbing', 'Layout Approval', 'Payment Method']
descriptionsCombined = ['Name: 1 super mega slab of igneous blue 3cm Counter SQFT: 20.0 Backsplash SQFT: 4.0', 'Using Material 1', 'Material 1. Laminated.', 'Material 1.', 'Material 1. " Corner Radius', 'Material 1.', 'Material 2 - From a Remnant Location: NFM', 'Using Material 2 Height: 24.0"', 'Material 2.', 'Material 2.', 'Material 3. Name: 1 jumbo slab calactatta gold 2cm Counter SQFT: 55.0 Backsplash SQFT: 8.0', 'Using Material 3', 'Material 3. Laminated.', 'Material 3.', '1.0 Undermount Double Sink Cutout(s) 1.0 Undermount Single Sink Cutout(s) 1.0 Overmount Double Sink Cutout(s) 1.0 Overmount Single Sink Cutout(s) 1.0 Appliance Cutout(s) 1.0 Outlet Cutout(s) 1.0 Faucet Hole(s) ', '', '', '', '', '', '', '', 'Cobra', 'Leoploredon', 'Ready for Template: No - Waiting on cabinets', '', '', "NOT a 'Rush Job'", 'Install on or Before: 03-22-2023', 'Sinks Requiring Plumbing: 2.0 Bath Sinks 1.0 Kitchen Sinks - Other Plumbing Items: Installation of Garbage Disposal Installation of Water Filter ', '', 'Credit Card (3% Charge)']
quantitiesCombined = ['1.0', '4.0', '5.0', '20.0', '3.0', '2.0', '32.0', '5.0', '5.0', '32.0', '1.0', '8.0', '22.0', '55.0', '1', '1.0', '1.0', '1.0', '1.0', '1.0', '1.0', '1.0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1']
pricesCombined = ['2560.0', '128.0', '42.0', '10.0', '125.0', '375.0', '62.0', '62.0', '0.0', '2.0', '5280.0', '96.0', '42.0', '2.0', '770.0', '485.0', '850.0', '420.0', '90.0', '100.0', '350.0', '75.0', '120.0', '560.0', '0', '1070.0', '750.0', '0', '1854.2', '1150.0', '0', '598.521']

# Outputs
productsString = ""
descriptionsString = ""
quantitiesString = ""
pricesString = ""

for i in range(0,len(productsCombined)):
    print(productsCombined[i])
    linesProducts = math.ceil(len(str(productsCombined[i])) / 47)
    linesDescriptions = math.ceil(len(str(descriptionsCombined[i])) / 47)
    linesQuantities = 1
    linesPrices = 1
    maxLines = max(linesProducts, linesDescriptions)
    if linesProducts >= maxLines:
        productsString += "\n" + "\n" + str(productsCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesProducts
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        productsString += "\n" + "\n" + str(productsCombined[i]) + additionalLines + "_____________________________________"
    if linesDescriptions >= maxLines:
        descriptionsString += "\n" + "\n" + str(descriptionsCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesDescriptions
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        descriptionsString += "\n" + "\n" + str(descriptionsCombined[i]) + additionalLines + "_____________________________________"
    if linesQuantities >= maxLines:
        quantitiesString += "\n" + "\n" + str(quantitiesCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesQuantities
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        quantitiesString += "\n" + "\n" + str(quantitiesCombined[i]) + additionalLines + "_____________________________________"
    if linesPrices >= maxLines:
        pricesString += "\n" + "\n" + str(pricesCombined[i]) + "\n_____________________________________"
    else:
        additionalLines = "\n"
        linesToAdd = maxLines - linesPrices
        for i in range(0, linesToAdd):
            additionalLines += "\n"
        pricesString += "\n" + "\n" + str(pricesCombined[i]) + additionalLines + "_____________________________________"
    print(productsCombined[i])
    print("\n")

答案1

得分: 0

如果想要像您的图像一样打印输出,可以使用以下代码:

import textwrap
from itertools import zip_longest

# ... 这里是数据列表 ...

value_widths = [35, 35, 10, 10]  # 为每列指定宽度

for values in zip(productsCombined, descriptionsCombined, quantitiesCombined, pricesCombined):
    # 使用 `textwrap.wrap` 将值换行到一个或多个宽度为 `width` 字符的行上
    # (如果有非常长的单词,它可能会更长);使用 `zip` 
    # 同时迭代列宽度
    wrapped_values = [textwrap.wrap(value, width) for value, width in zip(values, value_widths)]
    # 遍历换行后的行,使用 `zip_longest` 来处理“单元格”
    # 中的行数不同的情况,以确保它们能够正确工作
    for line in zip_longest(*wrapped_values, fillvalue=""):
        # 对齐每个单元格为精确的宽度字符
        # (这将无情地剪裁非常长的单词!)
        justified_line = [value.ljust(width)[:width] for value, width in zip(line, value_widths)]
        # 打印出单元格行,之间以空格分隔
        print(" ".join(justified_line))
    # 打印出行分隔线
    print(" ".join("_" * width for width in value_widths))

这将打印出:

Silestone                           Name: 1 super mega slab of igneous  1.0        2560.0    
                                    blue 3cm Counter SQFT: 20.0                              
                                    Backsplash SQFT: 4.0                                     
___________________________________ ___________________________________ __________ __________
4in. Backsplash                     Using Material 1                    4.0        128.0     
___________________________________ ___________________________________ __________ __________
Half-Bullnose Edge                  Material 1. Laminated.              5.0        42.0      
___________________________________ ___________________________________ __________ __________
[... 剪切 ...]

如果您确实需要将每列作为单独的列表,也很容易:

output_lines = []
for values in ...:
    # ... 不要打印对齐的行,而是将列表附加到 output_lines
    output_lines.append([value.ljust(width)[:width] for value, width in zip(line, value_widths)])
    # ... 不要打印分隔线,而是将列表附加到 output_lines
    output_lines.append(["_" * width for width in value_widths])
# ... 最后,使用 `zip(*...)` 模式将 N 长度的 4 列列表转置为 4 个 N 长度的元组:

a, b, c, d = zip(*output_lines)

然后 b 将以如下形式开始:

('Name: 1 super mega slab of igneous ', 'blue 3cm Counter SQFT: 20.0        ', 'Backsplash SQFT: 4.0               ', '___________________________________',

等等。

英文:

If the idea is to get a printout like in your image, then you can get away with simply:

import textwrap
from itertools import zip_longest

# ... the data lists here ...

value_widths = [35, 35, 10, 10]  # specify a width for each column

for values in zip(productsCombined, descriptionsCombined, quantitiesCombined, pricesCombined):
    # Use `textwrap.wrap` to line-wrap the values onto 1 or more lines of `width` characters
    # (could be longer if there's a very long word); use `zip` 
    # to iterate over the column widths in parallel
    wrapped_values = [textwrap.wrap(value, width) for value, width in zip(values, value_widths)]
    # Iterate over the wrapped lines, using `zip_longest` so "cells"
    # with less lines than others work correctly (as opposed to `zip`
    # that would use the shortest iterable)
    for line in zip_longest(*wrapped_values, fillvalue=""):
        # Justify each cell to exactly width characters
        # (this will ruthlessly clip very long words!)
        justified_line = [value.ljust(width)[:width] for value, width in zip(line, value_widths)]
        # Print out the cell lines, with a space in between
        print(" ".join(justified_line))
    # Print out the row divider lines
    print(" ".join("_" * width for width in value_widths))

This prints out

Silestone                           Name: 1 super mega slab of igneous  1.0        2560.0    
                                    blue 3cm Counter SQFT: 20.0                              
                                    Backsplash SQFT: 4.0                                     
___________________________________ ___________________________________ __________ __________
4in. Backsplash                     Using Material 1                    4.0        128.0     
___________________________________ ___________________________________ __________ __________
Half-Bullnose Edge                  Material 1. Laminated.              5.0        42.0      
___________________________________ ___________________________________ __________ __________
[... snip ...]

You could further adjust this to use .rjust for the numeric columns for a better layout.

If you really do need each column as a separate list, that's easy too:

output_lines = []
for values in ...:
    # ... instead of printing the justified line, append the list
    output_lines.append([value.ljust(width)[:width] for value, width in zip(line, value_widths)])
    # ... and instead of printing the divider, append the list
    output_lines.append(["_" * width for width in value_widths])
# ... finally, use the `zip(*...)` pattern to transpose the N-length list of 4 columns to a 4-tuple of N-length tuples:

a, b, c, d = zip(*output_lines)

b will then start with

('Name: 1 super mega slab of igneous ', 'blue 3cm Counter SQFT: 20.0        ', 'Backsplash SQFT: 4.0               ', '___________________________________', 

etc.

huangapple
  • 本文由 发表于 2023年3月7日 07:00:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75656602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定