当调用递归函数对值进行排序时,它会丢失一个值。我该怎么解决这个问题?

2024-09-27 17:33:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个递归函数,它从一个文件中读取一个scout记录列表,然后按其ID的顺序添加到一个列表框中。用addScouts(1)调用函数。函数如下:

def addScouts(self,I):
    i = I
    with open(fileName,"r") as f:
        lines = f.readlines()
        for line in lines:
            if str(line.split(",")[3])[:-1] == str(i):
                self.scoutList.insert(END,line[:-1])
                i += 1
                return self.addScouts(i)
    return

我的问题是我的文件ID是有序的1,2,4,5,因为在某个时候我删除了ID为3的scout。但是,当我运行函数在列表框(上面的函数)中对侦察兵重新排序时,它只列出ID 3之前(包括ID 3)的侦察兵。这是因为当i = 3时,文件中的所有项都不等于3,因此函数到达末尾并在有机会检查其余记录之前返回。你知道吗

文件内容:

Kris,Rice,17,1
Olly,Fallows,17,2
Olivia,Bird,17,4
Louis,Martin,18,5

你知道怎么解决吗?你知道吗


Tags: 文件函数selfid列表return顺序记录
2条回答

只需按最后一列排序:

 sorted(f,key=lambda x: int(x.split(",")[-1]))

您可以使用对分查找新数据的放置位置,以便在对数据排序一次后保持数据的有序性:

from bisect import bisect
import csv
with open("foo.txt") as f:
    r = list(csv.reader(f)) 
    keys = [int(row[-1]) for row in r]
    new = ["foo","bar","12","3"]
    ind = bisect(keys, int(new[-1]))
    r.insert(ind,new)
    print(r)

输出:

[['Kris', 'Rice', '17', '1'], ['Olly', 'Fallows', '17', '2'], ['foo', 'bar', '12', '3'], ['Olivia', 'Bird', '17', '4'], ['Louis', 'Martin', '18', '5']]

一种更简单的方法是检查第一行是否具有更高的id,如果没有更高的id,只需附加到末尾:

import csv
with open("foo.txt") as f:
    r = list(csv.reader(f))
    new = ["foo","bar","12","3"]
    key = int(new[-1])
    ind = None
    for i, row in enumerate(r):
        if int(row[-1]) >= key:
            ind = i
            break
    r.insert(ind, new) if ind is not None else r.append(new)
    print(r)

输出:

 [['Kris', 'Rice', '17', '1'], ['Olly', 'Fallows', '17', '2'], ['foo', 'bar', '12', '3'], ['Olivia', 'Bird', '17', '4'], ['Louis', 'Martin', '18', '5']

为了在添加新值时始终保持文件的有序性,我们只需写入临时文件,将行写入正确的位置,然后用更新的文件替换原始文件:

import csv
from tempfile import NamedTemporaryFile
from shutil import move


with open("foo.csv") as f, NamedTemporaryFile(dir=".", delete=False) as temp:
    r = csv.reader(f)
    wr = csv.writer(temp)
    new = ["foo", "bar", "12", "3"]
    key, ind = int(new[-1]), None
    for i, row in enumerate(r):
        if int(row[-1]) >= key:
            wr.writerow(new)
            wr.writerow(row)
            wr.writerows(r)
            break
        wr.writerow(row)
    else:
        wr.writerow(new)
move(temp.name, "foo.csv")

你知道吗foo.csv文件之后,数据将按顺序排列:

Kris,Rice,17,1
Olly,Fallows,17,2
foo,bar,12,3
Olivia,Bird,17,4
Louis,Martin,18,5

您可以检查列表的长度是否与文件的长度相同,如果不相同,则再次运行addScouts,如果为真,则结束。像这样:

def addScouts(self,I):
    i = I
    with open(fileName,"r") as f:
        lines = f.readlines()
        for line in lines:
            if str(line.split(",")[3])[:-1] == str(i):
                self.scoutList.insert(END,line[:-1])
                i += 1
                return self.addScouts(i)
    if len(scoutList) < len(lines):
        return self.addScouts(i+1)
    else:
        return

相关问题 更多 >

    热门问题