【问题标题】:merge nested lists into one by replacing the null value python通过替换空值python将嵌套列表合并为一个
【发布时间】:2020-08-13 10:53:19
【问题描述】:

我有一个列表,里面有几个嵌套列表,这里是示例:

temp_lst = [[None, None, None, None, None, None, None, '51', '51', '19'],
            [None, None, None, '55', '55', '55', '55', None, None, None],
            ['23', '23', '55', None, None, None, None, None, None, None]]

我想把它合并到一个列表中,并且值应该按照特定的顺序,结果需要完全像这样

           ['23', '23', '55', '55', '55', '55', '55', '51', '51', '19']

temp_lst 中可能有更多列表。

【问题讨论】:

标签: python


【解决方案1】:

你需要转置你的矩阵,然后过滤掉可能的候选者。

arr=[[None, None, None, None, None, None, None, '51', '51', '19'],
 [ None, None, None,'55', '55', '55', '55', None, None, None],
['23', '23', '55',None, None, None,None, None, None,None]]

ans=[]
for i in zip(*arr[::-1]):
    ans.append(list(filter(lambda x:x is not None, i))[0])
print(ans)

【讨论】:

  • 从过滤器创建一个列表并选择它的第一个元素有点浪费,如果一列中只有None,它将崩溃。也不需要反转输入列表 - 考虑到这一点 for i in zip(*arr): ans.append(filter(lambda x:x is not None, i)[0]) 就足够了。
【解决方案2】:

试试这个:

new_list = [n for sublist in original_list for n in sublist if n != None]

基本上我在这里所做的是使用列表推导。

【讨论】:

  • 感谢您的建议,但我想将值保持在相同的位置。就像列出的结果一样,23 应该是最终列表中的第一个。
  • 只需使用my_list[::-1] 反转列表即可
  • 它不是一个“扁平化”问题 - 解决方案在每个列表位置采用 not-None 值并保持它,忽略 Nones。
【解决方案3】:

您并没有真正扁平化您的列表,而是从子列表中的每个位置获取不是None 的值。

您可以使用zip() 按位置组合您的列表,并使用or 来获得不是None(或'' - 你没有)的值:

# you keep the vaue on each position thats not None 
data =  [[None, None, None, None, None, None, None, '51', '51', '19'],
         [None, None, None, '55', '55', '55', '55', None, None, None],
         ['23', '23', '55', None, None, None, None, None, None, None]]
# wanted ['23', '23', '55', '55', '55', '55', '55', '51', '51', '19']

def coalesque(iterable, default):
    """Returns the first truthy value from iterable or default."""
    for x in iterable:
        if x: 
            return x
    return default

result = [ coalesque(n,'') for n in zip(*data)]  

print(result)

将输出:

['23', '23', '55', '55', '55', '55', '55', '51', '51', '19']

只要您能确保:

  • 所有列表的长度都相同(其他研究 itertools.zip_longest)
  • 每个“列”只有 1 个不是 None 的元素(仅使用第一个)

使用defaultcoalesque(iterable,default) 来定义如果一个“列”中的所有值都是虚假的,应该返回什么。

见:

【讨论】:

    【解决方案4】:

    您可以使用 numpy 来执行此操作。 使用 Numpy,您可以展平任何维度的列表

    import numpy as np
    a  = [[None, None, None, None, None, None, None, '51', '51', '19'],
     [ None, None, None,'55', '55', '55', '55', None, None, None],
    ['23', '23', '55',None, None, None,None, None, None,None]]
    a = np.array(a) # Converting to numpy array
    a = a.flatten() # Flatten a list with numpy's builtin function
    a = [i for i in a if i != None] # Removing all occurences of None
    a = list(a) # Converting back to python list
    

    通过,您可以展平任何维度的列表

    【讨论】:

    • 它不是一个“扁平化”问题 - 解决方案在每个列表位置采用 not-None 值并保持它,忽略 Nones。
    【解决方案5】:

    虽然其他人已经发布了一个衬里,但如果您的列表中有更多层,这里有一个递归函数将起作用。

    def unstack_list(temp_list):
        # Construct list of elements to return
        answer = []
        for i in temp_list:
            # if element of list is list, recurse and concatenate lists
            if type(i) == list:
                answer = unstack_list(i) + answer
            # add to list if not None
            elif i is not None:
                answer.append(i)
        return answer
    

    【讨论】:

    • 感谢您的建议。但是结果是['51', '51', '19', '23', '23', '55', '55', '55', '55', '55'],不是按顺序排列的列出。并且'typeof'应该更改为'type'
    • 抱歉 - 已为您修复;基本上因为你想要相反的顺序,你可以翻转构造列表的连接方式,或者反转初始列表。
    • 但这只是一个例子,其他情况可能有不同的顺序,我不能简单地翻转它
    • 我们可以假设每个列表要么是一个列表列表,要么是一个值列表?不会有一个包含列表和值的列表吗?我现在明白你的问题是什么意思,但你最初的问题措辞很糟糕。我们是否还可以假设每个位置的值没有重叠?即 [[None, 1], [None, 2]] 不会发生?
    【解决方案6】:

    此解决方案保留每行的最后一个非 None 值,并跳过显示所有 None 值的任何位置。

    def crunchnones(data):
    """
    Assumes data is an iterable containing lists of values, and
        returns a single list of all non-None value in all lists in data,
        maintaining their positions inside each list.
    If no list contain a non-None value in a given position, that position
        will be silently skipped.
    If more than one list contains a non-None value in a given position,
        only the one in the last list will be returned.
    
    Example:
    >>> data =  [[None, None, None, None, None, None, None, '51', '51', '19'],
                 [None, None, None, '55', '55', '55', '55', None, None, None],
                 ['23', '23', '55', None, None, None, None, None, None, None]]
    >>> data2 =  [[None, None, None, None, None, None, None, '51', None, '19'],
                  [None, None, None, '55', '55', '55', '55', None, None, None],
                  [None, '23', '55', None, None, None, None, None, None, None]]
    >>> data3 =  [['21', None, None, None, None, None, None, '51', '51', '19'],
                  ['22', None, None, '55', '55', '55', '55', None, None, None],
                  ['23', '23', '55', None, None, None, None, None, None, None]]
    
    >>>crunchnones(data)
    ['23', '23', '55', '55', '55', '55', '55', '51', '51', '19']
    >>>crunchnones(data2)
    ['23', '55', '55', '55', '55', '55', '51', '19']
    >>>crunchnones(data3)
    ['23', '23', '55', '55', '55', '55', '55', '51', '51', '19']
    >>>
    """
    #
    temp = {}
    for riga in data:
        temp.update({i: x for i, x in enumerate(riga) if x is not None})
    return [temp[i] for i in sorted(temp)]
    

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 2016-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多