首页 > 解决方案 > 制作街头艺人名单

问题描述

已解决 :-) 我有这份清单,希望得到预期的结果,但没有运气。在 python 和 FME 中尝试过

如果当前数字与前一个数字之间的数字超过 2,则必须开始新行

有人可以帮忙吗?在 FME 中更可取,但在 python 中也可以

StreetName;HouseNumber;OddEven
Northroad;1;O
Northroad;2;E
Northroad;3;O
Northroad;4;E
Northroad;8;E
Northroad;10;E
Southroad;1;O
Southroad;2;E
Southroad;3;O
Southroad;4;E
Southroad;10;E
Southroad;12;E
Southroad;14;E

我的结果:

Northroad 1-3
Northroad 2-10
Southroad 1-3
Southroad 2-14

预期结果:

Northroad 1-3
Northroad 2-4
Northroad 8-10
Southroad 1-3
Southroad 2-4
Southroad 10-14

这有什么意义吗?

标签: pythonfme

解决方案


这是一个中等复杂度的解析、处理和格式化任务,所以我会使用类:一个用于道路一侧的连续地址范围,一个用于该范围的容器。这样加载界面就像添加一个解码的行一样简单,格式化界面也一样简单。

代码可以是:

# set the filenames here:
filename = "input.csv"
out = output.txt
class AddressRange:
    def __init__(self, row):
        self.road = row[0]
        self.low = self.high = int(row[1])
        self.side = row[2]

    def add(self, row):
        if (self.road != row[0]) or (self.side != row[2]):
            return False
        val = int(row[1])
        if val < self.low <= val+2:
            self.low = val
        elif val-2 <= self.high < val:
            self.high = val
        else:
            return False
        return True
    def __str__(self):
        return '%s %d-%d' % (self.road, self.low, self.high)

class AddressList:
    def __init__(self):
        self.ranges = []
    def add(self, row):
        for ar in self.ranges:
            if ar.add(row):
                break
        else:
            self.ranges.append(AddressRange(row))
    def print(self, fd=sys.stdout):
        for ar in self.ranges:
            print(str(ar), file=fd)


with open(filename) as fd:
    rd = csv.reader(fd, delimiter = ';')
    lst = AddressList()
    _ = next(fd)              # skip header line
    for row in rd:
        if len(row) == 3:
            lst.add(row)

with open(out, 'w') as fd:
    lst.print(out)

使用示例输入文件,输出如预期:

Northroad 1-3
Northroad 2-4
Northroad 8-10
Southroad 1-3
Southroad 2-4
Southroad 10-14

推荐阅读