我遇到一些困难,想出一种有效的方法来获取字符串列表并将其转换为元组对。我有一个类似于:
的列表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 :(得分:3)
一个可能的解决方案,我们可以先对列表进行排序,然后按每个术语的颜色部分进行分组,并将每个组转换为元组,如果它只包含一个元素,则在元组中插入一个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')]
答案 1 :(得分: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
结果如下:
[(None, 'green-s'), ('red-l', 'red-s'), ('blue-l', 'blue-s')]
答案 2 :(得分: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个单独的元素列表,因此这比其他选项稍快一些,因此查找速度更快。
答案 3 :(得分: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')]
使用该方法,您只需要在原始列表上移动一次,在色键上移动一次(更小)。
对字典的访问平均为O(1)
,因此应该足够快。
答案 4 :(得分:-3)
查看itertools.product()
功能。这将返回两个列表的笛卡尔积。在你的情况下你可以做到,
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))