1

因此,假设我在列表 A 中有一个包含 200 个数值的列表。我想创建一个列表 B,将列表 A 分成 4 个集群,所以我会得到 50 个集群。在列表 BI 中,希望为每个包含 4 个值的集群创建一个列表,因此列表 B 中将包含 50 个列表。

我将使用我的来源解释我的问题:

    from pprint import pprint

    FileValuelist = []

    def DetermineClusterNumber(File):               #determine digits in a cluster
            Lines = open(File, "r")
            i = 0 # used for iterating through the lines
            FirstLine = Lines.readline()
            for char in FirstLine:                  # read through first line, till hyphen.
                    if char != "-":
                            i += 1
                    elif char == "-":
                            return i # Return number of digits in the cluster 

    def ReadLines(File, Cluster_Number):
            Lines = open( File, "r" )
            for Line in Lines:
                    for char in Line:
                            if char != "-":
                                            FileValuelist.append(char)

    def RemoveNewlines(Rawlist):
            for x in range(len(FileValuelist)-9):
                    if FileValuelist[x] == "\n":
                            FileValuelist.remove(FileValuelist[x])
                    if FileValuelist[x] == "\r":
                            FileValuelist.remove(FileValuelist[x])


    Cluster_Number = DetermineClusterNumber("Serials.txt") # Amount of chars in a cluster. Example: 1234-2344-2345. clusternumber = 4
    ReadLines ("Serials.txt", Cluster_Number)
    RemoveNewlines(FileValuelist)

    list_iterater = 0

    FinishedList = ([[None]*(Cluster_Number)])*((len(FileValuelist)))
    amount_of_clusters = len(FileValuelist)/Cluster_Number

    for x in range(0, amount_of_clusters):
            for y in range(0, Cluster_Number):
                    FinishedList[x][y] = FileValuelist[list_iterater]
                    list_iterater += 1

    pprint(FinishedList)

使用 serials.txt 包含:

    4758-8345-1970-4486-2348
    2346-1233-3463-7856-4572
    6546-6874-1389-9842-4185
    9896-4688-4689-6455-4712
    9541-5621-8414-7465-5741
    4545-9959-5632-6845-1351
    5643-2435-5854-6754-8749
    7892-3457-8923-4572-5397
    5623-5698-5468-5476-9874
    8762-3487-6123-7861-2679

当我运行它时,我希望它在一个包含 50 个拆分 50 个列表的列表中打印 serials.txt。但是,当我运行它时,它会打印出 [2,6,7,8] 五十次。那是最后一个集群。所以我猜问题出在第 39 行的某个地方。我已经尝试查看在第 41 行为 FinishedList 分配了什么值,并且每次都是正确的值(所以不是 2、6、7、9,就像列表是打印出来)。我已经重新检查了 x 和 y 迭代器(是的,我知道它是拼写迭代器),它们也是正确的。

那么我的代码有什么问题使它打印最后一个集群五十次?顺便说一句,如果你不知道,我正在使用 Python 2.7。

提前致谢!

4

5 回答 5

1

这条线没有做你认为它正在做的事情:

FinishedList = ([[None]*(Cluster_Number)])*((len(FileValuelist)))

它存储对同一[None, None, None... None]列表的引用,len(FileValuelist)时间(*操作员基本上执行浅拷贝)。如果要确保它创建列表,最简单的方法是使用列表推导

FinishedList = [[None] * Cluster_Number for _ in xrange(len(FileValuelist))]
于 2012-12-17T17:12:21.823 回答
0

该行的第二个乘法FinishedList = ([[None]*(Cluster_Number)])*((len(FileValuelist)))实际上并没有创建len(FileValuelist)新列表,只是创建了许多指向原始列表的指针。当你改变其中任何一个时,它们都会改变。不久前我问了同样的问题,请参阅那里接受的答案。

于 2012-12-17T17:11:35.367 回答
0

您初始化的方式FinishedList,最终会得到一个列表,其中包含对同一子列表的引用。然后,当您分配给 时[x][y],您将覆盖每次反复引用的相同值。您不需要在 Python 中初始化列表,因此请尝试append()在第二个循环中使用。

for x in range(amount_of_clusters):
    offset = x * Cluster_Number
    FinishedList.append(FileValueList[offset:offset + Cluster_Number])
于 2012-12-17T17:12:08.437 回答
0

你为什么要以如此复杂的方式来做呢?你可以用两行代码完成你想要的:

>>> with open('serials.txt') as data: 
...    clusters = [[int(digit) for digit in cluster] for line in data for cluster in line.strip().split('-')]

然后clusters包含:

[
    [4, 7, 5, 8],
    [8, 3, 4, 5],
    [1, 9, 7, 0],
    # ...
]
于 2012-12-17T18:11:52.497 回答
0

伙计,没有冒犯,但你的代码非常不符合 Python 标准 - 寻找一些关于代码样式和列表的教程。这整个问题(如果我理解正确的话)可以用几行简单的代码来解决。

据我了解,您希望将文件中的每个四位数值转换为其数字列表并将这些数字存储在另一个列表中,这意味着输入

"1234-5678-9999"

结果应该是

[[1,2,3,4], [5,6,7,8], [9,9,9,9]]

这可以像这样简单地实现:

with open("serials.txt") as f:
    clusters = [c for line in f for c in line.strip().split("-")]
    digits = [list(c) for c in clusters]

Digits 现在包含每个集群的字符列表。如果您需要将值作为整数,您可以更改list(c)为嵌套列表理解,例如[int(x) for x in c].

于 2012-12-17T18:14:18.963 回答