首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于第n个字符的列表分组和格式设置

基于第n个字符的列表分组和格式设置
EN

Stack Overflow用户
提问于 2017-02-06 12:47:52
回答 2查看 410关注 0票数 0

输入:

我有一个文件,在每个换行符中有数千个长度相同的字符串(如上面所列的5个字符)。以下是该文件中每个字符串的属性,

  • 所有的字符串长度相同-5个字符.
  • 字符串的前3个字符可以称为“模式”(即上面示例中的abc、aef )。
  • 每个字符串的第四个字符称为“版本”。它只能有三个可能的数值- M/L/K (如上文所述)。最后一个字符是该字符串的“唯一ID”,该字符串表示为数字(它可以有值1、2、3)。

目标/预期产出:

  • 将该文件中的字符串条目写入按"version“分组的单独列(即字符串的L/M/K-4字符)。
  • 在每一列下,字符串应根据“模式”(即字符串的前3个字符)分组,并按“模式”的“唯一ID”(例如)的升序排列。(上述输出中的第二列L)。
  • 一个给定家庭跨多个“版本”的通用“唯一ID”应该安排在同一行(例如。(上述输出中的第一项)。但是,如果对给定的变量没有等效的“唯一ID”,那么它应该标记为"-“。

输入/输出

代码语言:javascript
复制
Input

abc**M**1
abc**L**1
aef**L**2
aef**K**3

Output

   M        L         K
  abcM1    abcL1       -
    -      aefL2       -
    -        -       aefK3

我被建议使用迭代工具中的"groupby“函数,这有助于根据”第4“字符对字符串进行分组。但是,我确信不能像上面的输出那样以所需的格式打印这些列表。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-06 13:39:14

这可能不是最短的答案,但应该相当容易读懂。

主要目标是构建条目的2d地图:

  1. 1级格式键(“abc”,1)
  2. “M”、“L”、“K”的第2级键

下面是一个示例,您可以根据需要更新print_entries

代码语言:javascript
复制
inputs = ['abcM1', 'abcL1', 'aefL2', 'aefK3']

def parse_inputs(inputs):
    entries = dict()    # key (abc,1), key ['M', 'L', 'K']

    for input_string in inputs:
        # parse and break down
        version = input_string[3]
        unique_id = int(input_string[4])
        key = (input_string[:3], unique_id)

        # put in ditionary
        if key not in entries:
            entries[key] = dict()
        entries[key][version] = input_string
    return entries

def print_entries(entries):
    ids = ['M', 'L', 'K']
    print '{:^6} {:^6} {:^6}'.format(*ids)
    for key in sorted(entries.keys()):
        cur_entries = entries[key]
        # for each id, find the entry, if not found, use placeholder '_'
        outputs = [cur_entries[_id] if _id in cur_entries else '_' for _id in ids]
        print '{:^6} {:^6} {:^6}'.format(*outputs)

entries = parse_inputs(inputs)
print_entries(entries)

产出如下:

代码语言:javascript
复制
  M      L      K   
abcM1  abcL1    _   
  _    aefL2    _   
  _      _    aefK3 
票数 0
EN

Stack Overflow用户

发布于 2017-02-06 12:59:07

首先必须使用sorted函数根据第5个索引对列表进行排序,然后根据第5个索引调用itertools.groupby (使用operator.itemgetter实现这一点)。例如:

代码语言:javascript
复制
>>> from operator import itemgetter
>>> from itertools import groupby
>>> my_list = ['abc**M**1', 'abc**L**1', 'aef**L**2', 'aef**K**3', 'xyz**M**3']

>>> [[i.replace('*', '') for i in j] for _, j in groupby(sorted(my_list, key=itemgetter(5)), key=itemgetter(5))]
[['aefK3'], ['abcL1', 'aefL2'], ['abcM1', 'xyzM3']]
#    ^           ^                    ^
#    K-Group     L-Group              M-Group

根据问题中提到的例子,看起来您的列表已经排序了。如果是这样的话,您可以跳过排序部分。

现在你们每一组都有篮子。以填充空的-。您可以创建一个for循环如下:

代码语言:javascript
复制
# same value extracted from above code
group_basket  = [['aefK3'], ['abcL1', 'aefL2'], ['abcM1', 'xyzM3']]

depth = 3

for b in group_basket:
    for i in range(depth):
        if i >= len(b) or not b[i].endswith(str(i+1)):
            b.insert(i, '-')

group_basket持有的最终值为:

代码语言:javascript
复制
>>> group_basket
[['-', '-', 'aefK3'], 
 ['abcL1', 'aefL2', '-'], 
 ['abcM1', '-', 'xyzM3']]

您可以使用zip以所需格式打印数据如下:

代码语言:javascript
复制
for x in zip(*group_basket[::-1]):
    print('\t'.join(x))

# which prints:
# --------------------
# abcM1  abcL1    -
#  -     aefL2    -
# xyzM3   -      aefK3
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42068209

复制
相关文章

相似问题

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