字符串到元组对的Python列表
我很难想出一种有效的方法来获取字符串列表并将其转换为元组对。我的清单类似于:字符串到元组对的Python列表,python,list,tuples,Python,List,Tuples,我很难想出一种有效的方法来获取字符串列表并将其转换为元组对。我的清单类似于: 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')] 我认为正则表达式是必要的,但我
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')]
我认为正则表达式是必要的,但我不知道如何做到这一点。非常感谢您的帮助。谢谢查看
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))
查看
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))
一种可能的解决方案是,我们可以先对列表进行排序,然后根据每个词的颜色部分进行分组,并将每个组转换为一个元组,如果它只包含一个元素,则在元组中插入一个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')]
一种可能的解决方案是,我们可以先对列表进行排序,然后根据每个词的颜色部分进行分组,并将每个组转换为一个元组,如果它只包含一个元素,则在元组中插入一个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')]
我编写的这个函数远非完美,但它提供了您希望的结果:
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')]
我编写的这个函数远非完美,但它提供了您希望的结果:
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')]
输出:
[('blue-l', 'blue-s'), ('red-l', 'red-s'), (None, 'green-s')]
由于将元素拆分为两个单独的列表,因此查找速度将略快于备选方案
输出:
[('blue-l', 'blue-s'), ('red-l', 'red-s'), (None, 'green-s')]
由于将元素分为两个单独的列表,因此查找速度略快于备选方案。我认为一个好的(也许更好)解决方案是:
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)
,因此应该足够快。我认为一个好的(也许更好)解决方案是:
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)
,因此应该足够快。列表的长度列表的条目不得超过~10000条。列表的长度列表的条目不得超过~10000条。但这假设OP有两个或更多个列表。如果(如问题中所示)只有一个多个不同字符串的列表该怎么办这是一个基于OP提供的用例示例的简单解决方案。我将让OP决定是否需要更灵活的方法。OP不需要笛卡尔积。查看示例输出。你给6个元组,样本是3。在我看来,他只是不想写出所有可能的元组。不,我不需要所有值的笛卡尔积。不过,谢谢你的回答。但这假设OP有两个或更多列表。如果(如问题中所示)只有一个多个不同字符串的列表该怎么办这是一个基于OP提供的用例示例的简单解决方案。我将让OP决定是否需要更灵活的方法。OP不需要笛卡尔积。查看示例输出。你给6个元组,样本是3。在我看来,他只是不想写出所有可能的元组。不,我不需要所有值的笛卡尔积。不过,谢谢你的回答。