2016-07-15 8 views
1

文字列のリストをタプルペアに変換する効率的な方法がいくつかあります。この例ではPythonリストを組にする文字列のリスト

listOfNames = ['red-l','blue-l','green-s','red-s','blue-s'] 

すべての色(赤、青、緑)「-l」または「-s」エントリのいずれかまたは両方を有している:私は次のようにリストを持っています。私は正規表現が必要とされていると思いますが、私はそうするかどうかはわからない

tupleOfNames = [('red-l','red-s'),(None,'green-s'),('blue-l','blue-s')] 

:私のようなタプルのペアに、文字列のリストを変換する必要があります。どんな助けでも大歓迎です。ありがとう

+0

リストの長さはどのくらいですか – GMarsh

+0

リストは〜10000を超えてはなりません。 – bsheehy

答えて

3

可能な解決策では、我々はまず、リストをソートし、各用語の色の一部をGROUPBYとタプルに各グループを変換する、それだけで一つの要素が含まれている場合はNoneを挿入することはできませんタプルで:

import re 
from itertools import groupby 

li = [] 
listOfNames.sort() 
for k, g in groupby(listOfNames, lambda s: re.findall("(.*)-", s)): 
    liG = list(g) 
    if len(liG) == 1: 
     li.append((None, liG[0])) 
    else: 
     li.append(tuple(liG)) 

li 
# [('blue-l', 'blue-s'), (None, 'green-s'), ('red-l', 'red-s')] 
-3

itertools.product()の機能をチェックしてください。これは、2つのリストのデカルト積を返します。あなたが行うことができ、あなたの場合、

from itertools import product 

l_names = ['red-l', 'blue-l'] 
s_names = ['red-s', 'blue-s', 'green-s'] 

tupleOfNames = list(product(l_names, s_names)) 
+0

しかし、これはOPに2つ以上のリストがあることを前提としています。多くの異なる文字列のリストが1つだけの場合(質問のように) – marcusshep

+0

これは、OPの提供するユースケースの例に基づく簡単な解決策です。彼はより柔軟なアプローチが必要かどうかを決定するためにそれをOPに残します。 – Danny

+1

OPにはデカルト積が必要ありません。サンプル出力を見てください。あなたは6つのタプルを与え、サンプルは3です。 –

0

私ははるかに完璧からです。この機能を書いたが、あなたが望む結果を提供します:

def tupleofnames(listofnames): 
     result = [] 
     colors = set([x[:-2] for x in listOfNames])  
     for c in colors:   
      if c+"-l" in listofnames: 
       if c+'-s' in listofnames: 
        result.append((c+"-l",c+'-s')) 
       else: 
        result.append((c+"-l",None)) 
      else: 
       result.append((None,c+"-s")) 
     return result 

結果は次のようになります ​​

0
listOfNames = ['red-l','blue-l','green-s','red-s','blue-s'] 
l_list = [a[:-2] for a in filter(lambda x:x[-1]=='l',listOfNames)] 
s_list = [a[:-2] for a in filter(lambda x:x[-1]=='s',listOfNames)] 
s = {a[:-2] for a in listOfNames} 
tuplesOfNames = [tuple([c+'-l' if c in l_list else None,c+'-s' if c in s_list else None]) for c in s] 

出力:その検索が少し速くなるよう

[('blue-l', 'blue-s'), ('red-l', 'red-s'), (None, 'green-s')] 

これ

は、要素のための2つの別々のリストにsplitingによる代替案よりもわずかに速くなります。

0

私は素敵な(そしておそらくより良い)ソリューションであると思う:

出力
from collections import defaultdict 
d = defaultdict(list) 
listOfNames = ['red-l','blue-l','green-s','red-s','blue-s'] 
# Go over the list and remember for each color the entry 
for s in listOfNames: 
    d[s[:-2]].append(s[-1]) 
# Go over the colors and produce the appropriate tuple 
[ (key+'-l' if 'l' in d[key] else None, key+'-s' if 's' in d[key] else None) for key in d.keys() ] 

[('blue-l', 'blue-s'), ('red-l', 'red-s'), (None, 'green-s')] 

を使用すると、元のリストの上に一つだけの時間と分の1つの時間に行くこと方法でカラーキー(より小さい)。

平均して辞書へのアクセスはO(1)なので、十分速く動作するはずです。