【问题标题】:Unique lists within list of lists if those lists have list as one of the elements列表列表中的唯一列表,如果这些列表将列表作为元素之一
【发布时间】:2020-11-20 01:55:46
【问题描述】:

如果我有:

l = [['98765', ['Einstein, A', 'SFEN'], 'SSW 540', 3], ['98765', ['Einstein, A', 'SFEN'], 'SSW 540', 3],
     ['98764', ['Feynman, R', 'SFEN'], 'SSW 564', 3], ['98764', ['Feynman, R', 'SFEN'], 'SSW 564', 3]]

什么是最好的获得方式:

k = [['98765', 'Einstein, A', 'SFEN', 'SSW 540', 3], ['98764', 'Feynman, R', 'SFEN', 'SSW 564', 3]]

如果我尝试:

uniqinstruct = set(map(tuple, l))

我收到TypeError: unhashable type: 'list'。我不想删除所有的嵌套层,因为那只会将所有内容合并到一个列表中:

output = []

def reemovNestings(l):
    for i in l:
        if type(i) == list:
            reemovNestings(i)
        else:
            output.append(i)

reemovNestings(l)
print(sorted(set(output), key=output.index))

输出:

['98765', 'Einstein, A', 'SFEN', 'SSW 540', 3, '98764', 'Feynman, R', 'SSW 564']

如果两个讲师的计数相同(在这种情况下为 3 个),则只剩下一个 3,因为它是一个 set,我不能按每个 x 间隔对列表中的元素进行分组。保留最后一个值的好方法是什么?

【问题讨论】:

  • 我们可以合并那些具有相同编号的列表,例如"98765""98764"
  • @jizhihaoSAMA 该数字是唯一标识符,但如果讲师教授多门课程(具有不同的课程名称和数量),则可能会重复,因此不适合合并
  • @KarlKnechtel 从django 看起来像flatten,然后每5个元素收集一次也可以

标签: python list function set tuples


【解决方案1】:

鉴于您知道要打开哪一层,您可以遍历该层。在您的特定示例中,它是第二层:

res = []
for inner_list in l:
    inner = []
    for el in inner_list:
        if type(el) == list:
            inner.extend(el)
        else:
            inner.append(el)
    if not (inner in res):
        res.append(inner)

请注意,list.extend 将多个值添加到列表中。

if not (inner in res): res.append(inner) 在顶层为您提供独特的物品。感谢@dmitryro 的提示。

【讨论】:

  • 您可能想查看if not (inner in res): res.append(inner),因为他只对非重复项感兴趣。
  • 是的,你是对的。在我完成代码剪切后,我在那里失明并意识到需要非重复元素。更新了答案。
【解决方案2】:

使用itertools.groupby 划分它们,并通过列表理解将它们展平。为了保证列表的顺序,你可以使用dict.fromkeys()

如果你不介意这个太长的列表理解:

from itertools import groupby

l = [['98765', ['Einstein, A', 'SFEN'], 'SSW 540', 3], ['98765', ['Einstein, A', 'SFEN'], 'SSW 540', 3],
     ['98764', ['Feynman, R', 'SFEN'], 'SSW 564', 3], ['98764', ['Feynman, R', 'SFEN'], 'SSW 564', 3]]

s = [list(dict.fromkeys(e for i in item for j in i for e in (j if type(j) is list else [j])).keys()) for _, item in groupby(l)]
print(s)

结果:

[['98765', 'Einstein, A', 'SFEN', 'SSW 540', 3], ['98764', 'Feynman, R', 'SFEN', 'SSW 564', 3]]

【讨论】:

  • Python 3.6 + 字典会保持插入顺序。
【解决方案3】:

Numpy.unique 与扁平列表一起使用。

np.unique(flattened, axis=0)

【讨论】:

  • print(sorted(set(output), key=output.index)) 更改为print(np.unique(output, axis=0))
【解决方案4】:

这是另一种可能的解决方案。

首先,将原始列表展平:

def flatten(s):
    if s == []:
        return s
    if isinstance(s[0], list):
        return flatten(s[0]) + flatten(s[1:])
    return s[:1] + flatten(s[1:])

您的原始输入:

l = [['98765', ['Einstein, A', 'SFEN'], 'SSW 540', 3], 
     ['98765', ['Einstein, A', 'SFEN'], 'SSW 540', 3],
     ['98764', ['Feynman, R', 'SFEN'], 'SSW 564', 3], 
     ['98764', ['Feynman, R', 'SFEN'], 'SSW 564', 3]]

现在让我们对其进行展平和迭代

final = [] # the resulting list

items = flatten(l) # first flatten the input

# take every 5 elements and add them to the final list, if not there yet.
for i in range(0, len(items), 5):
    if not (items[i:i+5] in final):
        final.append(items[i:i+5])

#let's print [['98765', 'Einstein, A', 'SFEN', 'SSW 540', 3], 
              ['98764', 'Feynman, R', 'SFEN', 'SSW 564', 3]]
print(final) 

【讨论】:

    猜你喜欢
    • 2017-04-12
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    相关资源
    最近更新 更多