2014-12-26 17 views
11

Dizideki ilk üç karaktere göre benzer öğeleri bir listede gruplandırmak istiyorum. Örneğin:Bir listede nasıl benzer öğeler gruplanır?

test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'] 

nasıl grup gruba Yukarıdaki liste öğeleri harfler (örn 'abc') ilk gruplaşma dayalı olabilir? Aşağıdaki amaçlanan çıktı şöyledir:

output = {1: ('abc_1_2', 'abc_2_2'), 2: ('hij_1_1',), 3: ('xyz_1_2', 'xyz_2_2')} 

yoksa başarılı olamadı Bunu gerçekleştirmek için itertools.groupby kullanarak denedi

output = [['abc_1_2', 'abc_2_2'], ['hij_1_1'], ['xyz_1_2', 'xyz_2_2']] 

:

>>> import os, itertools 
>>> test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'] 
>>> [list(g) for k.split("_")[0], g in itertools.groupby(test)] 
[['abc_1_2'], ['abc_2_2'], ['hij_1_1'], ['xyz_1_2'], ['xyz_2_2']] 

ben baktım başarı olmadan aşağıdaki mesajlar:

How to merge similar items in a list. Örnek, örneğim için aşırı karmaşık olan bir yaklaşımı kullanarak benzer öğeleri (ör. 'house' ve 'Hose') gruplandırır.

How can I group equivalent items together in a Python list?. Liste kavraması fikrini burada buldum.

cevap

8

.split("_")[0] bölümü, itertools.groupby numaralı ikinci argüman olarak ilettiğiniz tek argüman işlevi içinde olmalıdır. Sonuç hemen atılır beri

>>> import os, itertools 
>>> test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'] 
>>> [list(g) for _, g in itertools.groupby(test, lambda x: x.split('_')[0])] 
[['abc_1_2', 'abc_2_2'], ['hij_1_1'], ['xyz_1_2', 'xyz_2_2']] 
>>> 

for ... kısmen onu alarak hiçbir şey yapmaz. Yalnızca tek bir bölünmeyi istediğinizde Ayrıca


, str.partition kullanmak biraz daha verimli olacaktır:

[list(g) for _, g in itertools.groupby(test, lambda x: x.partition('_')[0])] 

Demo:

>>> from timeit import timeit 
>>> timeit("'hij_1_1'.split('_')") 
1.3149855638076913 
>>> timeit("'hij_1_1'.partition('_')") 
0.7576401470019234 
>>> 

Bu büyük bir endişe olarak değil Her iki yöntem de küçük dizeler üzerinde oldukça hızlıdır, ama ben bahsetmiştim.

+0

Teşekkürler, bu harika çalışıyor. Son zamanlarda girdi listesinin sıralandığından emin olmak için iyi bir uygulama olduğunu öğrendim. 'test = sıralanmış (['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2'])'. Aksi takdirde, giriş listesi sıralanmazsa, "itertools.groupby" beklendiği gibi çalışmayacaktır. – Borealis

+1

Evet, listeyi ilk sıralamak itertools.groupby'yi kullanırken iyi bir uygulamadır. Çünkü 'groupby' sadece benzer değerlerin çalışmasını yakalar. Anlam, liste sıralanmamışsa bazı özlüyor olabilir. Bunun ana konuğumun “groupby” nin nasıl kullanılacağı ve listenin zaten sıralandığından kaynaklandığından bahsetmedim. – iCodez

İlgili konular