英文:
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
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论