簡體   English   中英

如何將列表中的相同值分組到自己的列表中?

[英]How to group identical values from a list into their own lists?

說我有一個清單[2, 3, 7, 2, 3, 8, 7, 3] 2,3,7,2,3,8,7,3 [2, 3, 7, 2, 3, 8, 7, 3]

我想生成包含上面列表中相同值的列表。

預期輸出類似於:

[2, 2]
[3, 3, 3]
[7, 7]
[8]

生成這些列表的順序無關緊要。

最好的方法是使用collections.defaultdictO(n)解決方案:

>>> l = [2, 3, 7, 2, 3, 8, 7, 3]
>>> d = defaultdict(list)
>>> for e in l:
...     d[e].append(e)
... 
>>> d
defaultdict(<class 'list'>, {2: [2, 2], 3: [3, 3, 3], 7: [7, 7], 8: [8]})
>>> d.values()
dict_values([[2, 2], [3, 3, 3], [7, 7], [8]])

或者,您可以使用帶有排序列表的itertools.groupby

>>> for _, l in itertools.groupby(sorted(l)):
...     print(list(l))
... 
[2, 2]
[3, 3, 3]
[7, 7]
[8]

或者使用collections.Counter對列表進行理解:

>>> from collections import Counter
>>> [[i]*n for i,n in Counter(l).items()]
[[2, 2], [3, 3, 3], [7, 7], [8]]

正如我發布的那樣,defaultdict解決方案是O(n)並且比其他aproaches更快。 以下是測試:

from timeit import timeit


setup = (
"from collections import Counter, defaultdict;"
"from itertools import groupby;"
"l = [2, 3, 7, 2, 3, 8, 7, 3];"
)

defaultdict_call = (
"d = defaultdict(list); "
"\nfor e in l: d[e].append(e);"
)
groupby_call = "[list(g) for _,g in groupby(sorted(l))]"
counter_call = "[[i]*n for i,n in Counter(l).items()]"


for call in (defaultdict_call, groupby_call, counter_call):
  print(call)
  print(timeit(call, setup))

結果:

d = defaultdict(list); 
for e in l: d[e].append(e);
7.02662614302244
[list(g) for _,g in groupby(sorted(l))]
10.126392606005538
[[i]*n for i,n in Counter(l).items()]
19.55539561196929

這是現場測試

嘗試這個

l = [2, 3, 7, 2, 3, 8, 7, 3]
for i in set(l):
   print([i]*l.count(i))

輸出:

[8]
[2, 2]
[3, 3, 3]
[7, 7]

這是使用Counter進行此操作的簡短方法

from collections import Counter
my_dict = Counter([2, 3, 7, 2, 3, 8, 7, 3]) # returns {3: 3, 2: 2, 7: 2, 8: 1}

new_list = [[k] * v for k,v in my_dict.items()] 

輸出:

[[2, 2], [3, 3, 3], [7, 7], [8]]

一種方法是使用簡單的字典

l = [2, 3, 7, 2, 3, 8, 7, 3]

groups = {}
for n in l:
    groups.setdefault(n, []).append(n)

print(list(groups.values()))
# [[2, 2], [3, 3, 3], [7, 7], [8]]

在Numpy數組中執行此操作將非常有效

a= np.array([2, 3, 7, 2, 3, 8, 7, 3])
[a[a==i] for i in np.unique(a)]

輸出:

[array([2, 2]), array([3, 3, 3]), array([7, 7]), array([8])]

我想你可以試試collections.Counter,並在這個列表中獲得不同的密鑰及其計數。

from collections import Counter
l = [2, 3, 7, 2, 3, 8, 7, 3]
c =Counter(l)
print(c) ## result: {3: 3, 2: 2, 7: 2, 8: 1} 

這個答案是列表理解

l = [2, 3, 7, 2, 3, 8, 7, 3]

print(*[[i]*l.count(i) for i in set(l)], sep='\n')

輸出:

C:\Users\Desktop>py x.py
[8]
[2, 2]
[3, 3, 3]
[7, 7]

而且,輸出可以使用sorted()方法完全與您的輸出完全相同

l = [2, 3, 7, 2, 3, 8, 7, 3]

print(*sorted([[i]*l.count(i) for i in set(l)]), sep='\n')

OUTPUT:

C:\Users\Desktop>py x.py
[2, 2]
[3, 3, 3]
[7, 7]
[8]

編輯:當答案得到提升時,我想詳細解釋代碼,盡可能多地提供幫助。

代碼是這樣的:

 print(*[[i]*l.count(i) for i in set(l)], sep='\n')

使用set(l)消除重復值,並且在列表中僅保留[2, 3, 7, 8] 稍后,在[i]我們將set(l)每個元素放在一個新列表中。 我們計算i元素( iset(l )中的元素)在本機列表l發生的時間( l = [2, 3, 7, 2, 3, 8, 7, 3] )。 [i]*l.count(i) i在新列表中成為l.count(i)次。 List-comprehension方法在迭代完成后獲取所有值,並將其打包在列表中並返回列表。 *開頭的標志用於解壓縮返回列表中的值。 最后*print()* keyword sep='\\n'在解壓縮列表中的每個元素后放一個'\\n' 如果沒有它,可以這樣做:

for j in [[i]*l.count(i) for i in set(l)]:
    print(j)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM