【问题标题】:How to regroup tuples in list of list of tuples by checking the one of the tuple values?如何通过检查元组值之一来重新组合元组列表中的元组?
【发布时间】:2018-04-04 03:12:20
【问题描述】:

给定元组列表的输入列表:

input_lol = [ [('x', 'AA'), ('y', 'AB')], 
              [('yy', 'AB'), ('..', 'Punct'), ('foo', 'ZZ')], 
              [('y', 'AB')] 
            ]

所需的输出是重新组合元组的内部列表,使得在元组的第二个元素中包含'Punct' 的元组被挑出,并且在包含'Punct' 的元组之前的任何元组都被分组到前一个列表中。

例如所需的输出:

desired_lolol = [ [[('x', 'AA'), ('y', 'AB')], [('yy', 'AB')]], 
                 ('..', 'Punct'), 
                [[('foo', 'ZZ')], [('y', 'AB')]] 
              ]

另一个例子:

input_lol = [ [('x', 'AA'), ('y', 'AB')], 
              [('yy', 'AB'), ('..', 'Punct'), ('foo', 'ZZ')], 
              [('y', 'AB')], 
              [('ybar', 'CC')],
              [('z', 'NJ'), ('!', 'Punct')],
              [('pals', 'AJB')], 
            ]

desired_lolol = [ [[('x', 'AA'), ('y', 'AB')], [('yy', 'AB')]], 
                  ('..', 'Punct'), 
                  [[('foo', 'ZZ')], [('y', 'AB')]], [('ybar', 'CC')], [('z', 'NJ')],
                  ('!', 'Punct'),
                  [('pals', 'AJB')], 
              ]

另一个例子:

input_lol = [ [('x', 'AA'), ('y', 'AB')], 
              [('yy', 'AB'), ('..', 'Punct'), ('bar', 'YY'), ('..', 'Punct'), ('foo', 'ZZ')], 
              [('y', 'AB')], 
              [('ybar', 'CC')],
              [('z', 'NJ'), ('!', 'Punct')],
              [('pals', 'AJB')], 
            ]

desired_lolol = [ [[('x', 'AA'), ('y', 'AB')], [('yy', 'AB')]], 
                  ('..', 'Punct'), 
                  [('bar', 'YY')], 
                  ('..', 'Punct'), 
                  [[('foo', 'ZZ')], [('y', 'AB')]], [('ybar', 'CC')], [('z', 'NJ')],
                  ('!', 'Punct'),
                  [('pals', 'AJB')], 
              ]

我试过了:

desired_lolol = []
output_inner_lol = []

for inner_list_of_tuple in input_lol:
    if any(tag == 'Punct' for s, tag in inner_list_of_tuple):
        pending = []
        for s, tag in inner_list_of_tuple:
            if tag == 'Punct':
                desired_lolol.append(pending)
                desired_lolol.append((s,tag))
                pending = []
            else:
                pending.append((s,tag))
        if pending:
            desired_lolol.append((s,tag))
    else:
        desired_lolol.append(inner_list_of_tuple)

得到了这个:

[[('x', 'AA'), ('y', 'AB')],
 [('yy', 'AB')],
 ('..', 'Punct'),
 ('foo', 'ZZ'),
 [('y', 'AB')]]

但[('x', 'AA'), ('y', 'AB')] 和[('yy', 'AB')] 并没有组合到一个列表中。所以我不得不做一些后期处理:

desired_lolol = []
output_inner_lol = []

for inner_list_of_tuple in input_lol:
    if any(tag == 'Punct' for s, tag in inner_list_of_tuple):
        pending = []
        for s, tag in inner_list_of_tuple:
            if tag == 'Punct':
                desired_lolol.append(pending)
                desired_lolol.append((s,tag))
                pending = []
            else:
                pending.append((s,tag))
        if pending:
            desired_lolol.append((s,tag))
    else:
        desired_lolol.append(inner_list_of_tuple)

really_desired_lolol = []
pending = []
for x in desired_lolol:
    if type(x) == tuple and x[1] == 'Punct':
        really_desired_lolol.append(pending)
        really_desired_lolol.append(x)
        pending = []
    else:
        pending += x

if pending:
    really_desired_lolol.append(pending)

有没有更简单的方法来获取desired_lolol?

【问题讨论】:

  • 你能谈谈输入的性质吗,比如 Punct 元组只会在包含它们的子列表中出现一次>?
  • 点元组会出现多次。

标签: python list loops tuples


【解决方案1】:

您可以对任意深度的数据使用递归解决方案:

def get_punc(current):
    updated_data = [get_punc(i) if any(isinstance(c, list) for c in i) else i for i in current]
    new_data = iter(updated_data)
    final_data = []
    while True:
        result = next(new_data, None)
        if not result:
            return final_data

        if any(a == 'Punct' for _,a  in result):
            the_index = [i for i, a in enumerate(result) if a[1] == 'Punct'][0]
            if the_index > 0:
                final_data[-1].append(result[:the_index])
            final_data.append(result[the_index])
            if the_index < len(result)-1:
                final_data.append([result[the_index+1:]])
        else:

            if final_data and isinstance(final_data[-1], list):
                final_data[-1].append(result)
            else :
                if not final_data or not isinstance(final_data[-1], tuple):
                    final_data.append([result])  
                else: 
                    final_data.append([result])

输出:

[[[('x', 'AA'), ('y', 'AB')], [('yy', 'AB')]], ('..', 'Punct'), [[('foo', 'ZZ')], [('y', 'AB')]]]
--------------------
[[[('x', 'AA'), ('y', 'AB')], [('yy', 'AB')]], ('..', 'Punct'), [[('foo', 'ZZ')], [('y', 'AB')], [('ybar', 'CC')], [('z', 'NJ')]], ('..', 'Punct'), [('pals', 'AJB')]]
--------------------

【讨论】:

  • 现在看起来好多了,但并不像我想象的那么简单。
  • 等一下!最内层的 if else 没有区别。
  • @alvas 主要任务是需要维护原始输入的结构,标点符号元组除外。因此,代码必须考虑到非标点元组需要正确插入到正确位置的事实,因此解决方案稍长。
猜你喜欢
  • 1970-01-01
  • 2014-10-13
  • 2016-04-12
  • 2016-12-19
  • 2019-05-25
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多