Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
字符串到元组对的Python列表_Python_List_Tuples - Fatal编程技术网

字符串到元组对的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。在我看来,他只是不想写出所有可能的元组。不,我不需要所有值的笛卡尔积。不过,谢谢你的回答。