首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python导入作为复杂嵌套列表、排序和输出的文本或返回CSV

Python导入作为复杂嵌套列表、排序和输出的文本或返回CSV
EN

Stack Overflow用户
提问于 2017-07-19 14:13:05
回答 2查看 143关注 0票数 0

我有一个数据结构,我们称之为库存,在CSV中,类似于:

代码语言:javascript
复制
ResID,Building,Floor,Room,Resource
1.1.1.1,Central Park,Ground,Admin Office,Router
1.1.2.1,Central Park,Ground,Machine Closet,Router
1.3.1.1,Central Park,Mezzanine,Dungeon,Whip
2.1.3.1,Chicago,Roof,Pidgeon Nest,Weathervane
1.13.4.1,Central Park,Secret/Hidden Floor,c:\room,Site-to-site VPN for 1.1.1.1
1.2.1.1,Central Park,Balcony,Restroom,TP    

我试图让它以排序后的CSV格式输出,并以以下格式的文本文件格式输出:

代码语言:javascript
复制
1 Central Park
1.1 Ground
1.1.1 Admin Office
1.1.1.1 Router
1.1.2 Machine Closet
1.1.2.1 Router
1.2 Balcony
1.2.1 Restroom
1.2.1.1 TP
1.3 Mezzanine
1.3.1 Dungeon
1.3.1.1 Whip
1.13 Secret/Hidden Floor
1.13.4 c:\room
1.13.4.1 Site-to-site VPN for 1.1.1.1
2 Chicago
2.1 Roof
2.1.3 Pidgeon Nest
2.1.3.1 Weathervane

我设想的数据结构类似于:

代码语言:javascript
复制
Building = {
    1 : 'Central Park',
    2 : 'Chicago'
}
Floor = {
    1 : {
        1 : 'Ground',
        2 : 'Balcony',
        3 : 'Mezzanine',
        13: 'Secret/Hidden Floor'
    },
    2  : {
        1 : 'Roof'
    }
}

Room = {
    1 : {
        1 : {
            1 : 'Admin Office',
            2 : 'Machine Closet'
        }
        2 : {
            1 : 'Restroom'
        }
        3 : {
            1 : 'Dungeon'
        }
... Hopefully by now you get the idea.

我的复杂之处在于,我不知道这是否是表示数据的最佳方式,然后将其迭代为:

代码语言:javascript
复制
for buildingID in buildings:
    for floorID in floors[buildingID]:
        for roomID in rooms[buildingID][floorID]:
            for resource in resources[buildingID][floorID][roomID]:
                do stuff...

或者,如果有一种更理智的方式来用脚本来表示数据,但我需要完整的文档标题编号和名称,这是我能够在我的技能水平上可视化的唯一方法。

我也无法找到一种有效的方法来生成这些信息,并以这种格式从CSV构建到数据结构中。

对一些人来说,这似乎是微不足道的,但我并不是一个职业程序员,实际上我只是偶尔涉足一下。

我的最终目标是能够将CSV吸收到一个正常的数据结构中,按照升序对其进行适当的排序,在上面显示的文本结构中生成行条目,其中只列出每一栋建筑、楼层、房间和资源,并在彼此之间列出,然后表面上我处理文本输出或返回排序CSV将是微不足道的。

如有任何建议,将不胜感激。

编辑:解决方案

利用我下面接受的答案,我能够生成以下代码。谢谢你删除了他的答案和评论,简化了我的排序过程!

代码语言:javascript
复制
import csv

def getPaddedKey(line):
    keyparts = line[0].split(".")
    keyparts = map(lambda x: x.rjust(5, '0'), keyparts)
    return '.'.join(keyparts)

def outSortedCSV(reader):
    with open(fOutName, 'w') as fOut:
        writer = csv.writer(fOut, delimiter=',')
        head = next(reader)
        writer.writerow(head)
        writer.writerows(sorted(reader, key=getPaddedKey))

s = set()
fInName = 'fIn.csv'
fOutName = 'fOut.csv'

with open(fInName, 'r') as fIn:
    reader = csv.reader(fIn, delimiter=',')
    outSortedCSV(reader)
    fIn.seek(0)
    next(fIn)
    for row in reader:
        ids = row[0].split('.')      # split the id
        for i in range(1, 5):
            s.add(('.'.join(ids[:i]), row[i])) # add a tuple with initial part of id and name

for e in sorted(list(s), key=getPaddedKey):
    print e[0] + '  ' + e[1]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-19 16:11:16

如果您没有理由构建您建议的结构,您可以简单地为每一行添加建筑物、楼层、房间和资源以及它的id到一个集合(以自动消除重复)。然后将集合转换为列表,对其进行排序,您就完成了。

可能的Python代码,假设rd是清单(*)上的csv.reader

代码语言:javascript
复制
next(rd)                         # skip the headers line
s = set()
for row in rd:
    ids = row[0].split('.')      # split the id
    for i in range(1, 5):
        s.add(('.'.join(ids[:i]), row[i])) # add a tuple with initial part of id and name
l = list(s)                      # convert to a list
l.sort()                         # sort it

现在您有了一个2元组[('1', 'Central Park'), ('1.1', 'Ground'), ('1.1.1', 'Admin Office'), ...]的列表,您可以使用它构建一个新的csv,或者将它打印为文本:

代码语言:javascript
复制
for i in l:
    print(" ".join(i))

(*)在Python 3中,您可以使用:

代码语言:javascript
复制
with open(inventory_path, newline = '') as fd:
    rd = csv.reader(fd)
    ...

在Python 2中,应该是:

代码语言:javascript
复制
with open(inventory_path, "rb") as fd:
    rd = csv.reader(fd)
    ...
票数 0
EN

Stack Overflow用户

发布于 2017-07-19 15:03:48

提取身份证

代码语言:javascript
复制
ids = ['Building_id', 'Floor_id', 'Room_id', 'Resource_id']
labels = ['ResID', 'Building', 'Floor', 'Room', 'Resource']

df2 = df.join(pd.DataFrame(list(df['ResID'].str.split('.')), columns=ids))

df2

代码语言:javascript
复制
    ResID   Building    Floor   Room    Resource    Building_id     Floor_id    Room_id     Resource_id
0   1.1.1.1     Central Park    Ground  Admin Office    Router  1   1   1   1
1   1.1.2.1     Central Park    Ground  Machine Closet  Router  1   1   2   1
2   1.3.1.1     Central Park    Mezzanine   Dungeon     Whip    1   3   1   1
3   2.1.3.1     Chicago     Roof    Pidgeon Nest    Weathervane     2   1   3   1
4   1.13.4.1    Central Park    Secret/Hidden Floor     c:\room     Site-to-site VPN for 1.1.1.1    1   13  4   1
5   1.2.1.1     Central Park    Balcony     Restroom    TP  1   2   1   1

迭代这个

小辅助法

代码语言:javascript
复制
def pop_list(list_):
    while list_:
        yield list_[-1], list_.copy()
        list_.pop()


for (id_, remaining_ids), (label, remaining_labels) in zip(pop_list(ids), pop_list(labels)):

    print(label, ': ', df2.groupby(remaining_ids)[label].first())

返回

代码语言:javascript
复制
Resource :  Building_id  Floor_id  Room_id  Resource_id
1            1         1        1                                    Router
                       2        1                                    Router
             13        4        1              Site-to-site VPN for 1.1.1.1
             2         1        1                                     TP   
             3         1        1                                      Whip
2            1         3        1                               Weathervane
Name: Resource, dtype: object

Room :  Building_id  Floor_id  Room_id
1            1         1            Admin Office
                       2          Machine Closet
             13        4                 c:\room
             2         1                Restroom
             3         1                 Dungeon
2            1         3            Pidgeon Nest
Name: Room, dtype: object

Floor :  Building_id  Floor_id
1            1                        Ground
             13          Secret/Hidden Floor
             2                       Balcony
             3                     Mezzanine
2            1                          Roof
Name: Floor, dtype: object

Building :  Building_id
1    Central Park
2         Chicago
Name: Building, dtype: object

解释

代码语言:javascript
复制
for (id_, remaining_ids), (label, remaining_labels) in zip(pop_list(ids), pop_list(labels)):
    print((id_, remaining_ids), (label, remaining_labels))

返回

代码语言:javascript
复制
('Resource_id', ['Building_id', 'Floor_id', 'Room_id', 'Resource_id']) ('Resource', ['ResID', 'Building', 'Floor', 'Room', 'Resource'])
('Room_id', ['Building_id', 'Floor_id', 'Room_id']) ('Room', ['ResID', 'Building', 'Floor', 'Room'])
('Floor_id', ['Building_id', 'Floor_id']) ('Floor', ['ResID', 'Building', 'Floor'])
('Building_id', ['Building_id']) ('Building', ['ResID', 'Building'])

因此,这只是在你的建筑结构中的不同层次上迭代。

代码语言:javascript
复制
res = df2.groupby(remaining_ids)[label].first()

在您的结构中每个级别构建一个表示此级别上的项的DataFrame,并将嵌套的ID索引到这个级别。这是您想要的最终数据结构的信息,只需将其转换为嵌套的dict

代码语言:javascript
复制
Building_id  Floor_id
1            1                        Ground
             13          Secret/Hidden Floor
             2                       Balcony
             3                     Mezzanine
2            1                          Roof

发短信(没有嵌套)

代码语言:javascript
复制
res.index = res.index.to_series().apply('.'.join)
print(res)

1.1地面1.13秘密/隐蔽楼层1.2阳台1.3夹层2.1屋顶名称:楼层,dtype:物体

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45193210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档