如何在列表中找到相同的值并将新列表组合在一起?

Posted

技术标签:

【中文标题】如何在列表中找到相同的值并将新列表组合在一起?【英文标题】:How can I find same values in a list and group together a new list? 【发布时间】:2015-07-29 08:37:50 【问题描述】:

从此列表中:

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]

我正在尝试创建:

L = [[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]

发现相同的任何值都被分组到它自己的子列表中。 到目前为止,这是我的尝试,我想我应该使用while 循环吗?

global n

n = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] #Sorted list
l = [] #Empty list to append values to

def compare(val):
   """ This function receives index values
   from the n list (n[0] etc) """
   
   global valin
   valin = val

   global count
   count = 0

    for i in xrange(len(n)):
        if valin == n[count]: # If the input value i.e. n[x] == n[iteration]
            temp = valin, n[count]
             l.append(temp) #append the values to a new list
             count +=1
        else:
          count +=1
    

for x in xrange (len(n)):
    compare(n[x]) #pass the n[x] to compare function

【问题讨论】:

这是我目前的尝试 ...如果您的代码遇到任何问题,请提及。 为什么要存储所有的数字?为什么不把它折叠成一个包含两个值的元组列表。数字本身以及该数字出现的次数。 【参考方案1】:

使用itertools.groupby:

from itertools import groupby

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]

print([list(j) for i, j in groupby(N)])

输出:

[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

旁注:当您不需要需要时,请避免使用全局变量。

【讨论】:

注意:列表需要按照groupby使用的相同key进行排序,才能达到问题中预期的结果。否则例如对于N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1],您将获得[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]] @Sam Bruns 。例如,当N 具有随机值时,您的方法就不稳定。如果您想查看我要说的内容,只需在创建列表N 之后立即输入random.shuffle(N)。然后,你会看到 output 不一样,而@Burger King 的代码是稳定的。 @Spider:包含随机值的数组不是 OP 指定的任何要求。请确保您在发表评论之前完全理解问题。 @SamBruns 我非常肯定地说:“你的方法不稳定”,为了向观众展示如果有人想在这样的任何情况下使用,补充你的答案并没有错.当涉及到“未排序”列表时,您的方法肯定会失败,并且......请确保,我的评论是我想说的。 @Spider:您在这里定义为“稳定”和“不稳定”是任意的。也许 OP DO 希望解决方案以这种方式运行。可以想到许多不需要将所有值分组到单个列表中的用例。虽然您指出的行为可以作为注释提及(正如第一条评论中已经提到的那样),但它不能以任何方式定义为不稳定。请不要做出假设……要求。【参考方案2】:

有人提到N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1],它会得到[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]]

也就是说,当列表中的数字不按顺序排列或者是乱七八糟的列表时,它是不可用的。

所以我有更好的答案来解决这个问题。

from collections import Counter

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
C = Counter(N)

print [ [k,]*v for k,v in C.items()]

【讨论】:

太棒了托尼!我确实遇到了使用 itertools 解决方案进行索引的问题,所以这种方法效果很好,因为我不需要事先对列表进行排序!再次感谢您!【参考方案3】:

您可以将itertools.groupby 与list comprehension 一起使用

>>> l =  [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
>>> [list(v) for k,v in itertools.groupby(l)]
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

这可以分配给变量L

L = [list(v) for k,v in itertools.groupby(l)]

【讨论】:

【参考方案4】:

你把事情复杂化了。

您要做的是:对于每个值,如果它与最后一个值相同,只需将其附加到最后一个值列表中;否则,创建一个新列表。您可以直接将英语翻译成 Python:

new_list = []
for value in old_list:
    if new_list and new_list[-1][0] == value:
        new_list[-1].append(value)
    else:
        new_list.append([value])

如果您愿意更抽象一点,还有更简单的方法可以做到这一点,例如,通过使用itertools 中的分组函数。但这应该很容易理解。


如果您确实需要使用while 循环执行此操作,您可以将任何for 循环转换为while 循环,如下所示:

for value in iterable:
    do_stuff(value)

iterator = iter(iterable)
while True:
    try:
        value = next(iterator)
    except StopIteration:
        break
    do_stuff(value)

或者,如果您知道可迭代是一个序列,您可以使用稍微简单的while 循环:

index = 0
while index < len(sequence):
    value = sequence[index]
    do_stuff(value)
    index += 1

但这两者都会使您的代码可读性降低、Python 风格降低、更复杂、效率更低、更容易出错等等。

【讨论】:

非常好的答案(我喜欢蛮力),但是你能想出一个使用while 循环的方法吗?用 OP 的话 我在想我应该使用 while 循环吗? @BhargavRao:嗯,您总是可以将任何for 循环转换为while 循环。但你为什么要这样做? 对于这个问题,for 循环更适合。与 C 不同,py 翻译不是那么直接,尽管它们很容易。我只是要求给 OP 一个关于 while 循环的公平概念,它的复杂性。 D̶o̶ ̶c̶o̶n̶s̶i̶d̶e̶r̶ ̶d̶o̶i̶n̶g̶ ̶t̶h̶a̶t̶ ̶i̶n̶ ̶y̶o̶u̶r̶ ̶s̶p̶a̶r̶e̶ ̶t̶i̶m̶e̶ 那里很好:)【参考方案5】:

你也可以使用 numpy 来做到这一点:

import numpy as np

N = np.array([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
counter = np.arange(1, np.alen(N))
L = np.split(N, counter[N[1:]!=N[:-1]])

这种方法的优点是当您有另一个与 N 相关的列表并且您想以相同的方式对其进行拆分时。

【讨论】:

【参考方案6】:

另一个不依赖于 itertools 的稍微不同的解决方案:

#!/usr/bin/env python

def group(items):
    """
    groups a sorted list of integers into sublists based on the integer key
    """
    if len(items) == 0:
        return []

    grouped_items = []
    prev_item, rest_items = items[0], items[1:]

    subgroup = [prev_item]
    for item in rest_items:
        if item != prev_item:
            grouped_items.append(subgroup)
            subgroup = []
        subgroup.append(item)
        prev_item = item

    grouped_items.append(subgroup)
    return grouped_items

print group([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
# [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]

【讨论】:

以上是关于如何在列表中找到相同的值并将新列表组合在一起?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据原始列表相同的值但不同的索引创建新列表

Flutter 如何在 Firestore 中组合多个文档中的值以与列表中的相应卖家一起显示

如何从列表中删除两次包含相同数字的组合,其中重复包含相同的数字?

如何避免冗余并将过滤器应用于字符串组合

当我在循环中添加到字典时有新键时创建一个新列表

R如何排列数据帧的所有行,以便在列表中返回所有可能的行组合?